算法分析與設計——LeetCode Problem.24 Swap Nodes in Pairs

問題詳情

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

結點結構爲:

struct ListNode {
         int val;
         ListNode *next;
         ListNode(int x) : val(x), next(NULL) {}
};

問題分析及思路

最近忙期中的事,大概已經半個多月沒有碰過leetcode了,這是新的一道題,後面會多打一些。
這道題大致意思是將一個鏈表中相鄰兩個結點相交換,但是不能直接交換它們的值,必須交換它們的結點。剛開始接觸這道題我嘗試用一個while循環來做它,卻發現非常複雜,幾乎寫不出while循環來實現它。
認真思考後我發現這是一個遞歸問題,正好遞歸一直是我的弱項,這道題可以鍛鍊我的遞歸能力。
最後算法思路如下:

1.對函數swapTwoPairs傳入一個結點First,當First的下下個結點不爲空時,用結點Second保存它的下下個結點,Third保存它的下一個結點。使得First的下下個結點變爲它自己,First的下個結點變爲swapTwoPairs(Second)遞歸。遞歸完成後返回Third。
2.當First的下下個結點爲空時,用Third保存它的下個結點,使得First的下下個結點變爲它自己,它的下個結點爲NULL,返回Third。

以上算法思路有漏洞,只考慮了有偶數個結點的情況,沒有考慮爲奇數個結點的情況,故在算法前還要加一個判斷:
如果First的下個結點爲NULL,則直接返回First。
此外還要注意,當傳入一個空的鏈表時,還要檢查是否爲空。爲空就不進入遞歸,直接返回NULL。
由於本人對遞歸十分不熟悉,這道題收穫很多,它的遞歸次數大概是n個結點數除以2,即log2n次,時間複雜度爲O((log2n)2)。


具體代碼

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == NULL) {
            return NULL;
        }
        return swapTwoPairs(head);
    }
    ListNode* swapTwoPairs(ListNode* First) {
        if(First->next == NULL) {
            return First;
        }
        if(First->next->next != NULL) {
            ListNode* Second = First->next->next;
            ListNode* Third = First->next;
            First->next->next = First;
            First->next = swapTwoPairs(Second);
            return Third;
        } else {
            First->next->next = First;
            ListNode* Third = First->next;
            First->next = NULL;
            return Third;
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章