【LeetCode】24. Swap Nodes in Pairs(C++)
阿新 • • 發佈:2018-12-02
地址:https://leetcode.com/problems/swap-nodes-in-pairs/
題目:
Given a linked list, swap every two adjacent nodes and return its head.
Example:
Given 1->2->3->4, you should return the list as 2->1->4->3.
Note:
- Your algorithm should use only constant extra space.
- You may not
理解:
一開始就想到了直接改val
,一看note不允許。。那就直接改嘍。
為了處理連結串列的頭,加了個頭節點。用三個指標分別指向前一個,第一個和第二個節點。
修改的過程如下圖所示:
注意三個指標儲存了三個結點的地址,因此修改pr->next
一定要晚於讓pl->next=pr->next
。
實現1:
自己的實現,不過要比別人的慢一些。
下面更新了一版。
class Solution { public: ListNode* swapPairs(ListNode* head) { if (!head || !head->next) return head; ListNode* nHead = new ListNode(0); nHead->next = head; ListNode* pre = nHead; ListNode *pl = pre->next, *pr = pre->next->next; while (1) { pl->next = pr->next; pr->next = pl; pre->next = pr; if (pl->next&&pl->next->next) { pre = pl; pl = pre->next; pr = pl->next; } else break; } return nHead->next; } }; //後來仿照實現2修改的程式碼 class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode* pre = nullptr; ListNode* newHead=head; ListNode *pl = head, *pr=head; while (pl&&pl->next) { newHead = pl==pr ? pl->next : newHead; pr = pl->next; pl->next = pr->next; pr->next = pl; if (pre) { pre->next = pr; } pre = pl; pl = pl->next; } return newHead; } };
實現2
下面是別人的實現。
其中retval
只有第一次翻轉會更新,就是新的頭結點。巧妙的避免了要判斷是否是頭結點的情況。可能就是這裡省了一點時間?
class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode* retval = head; ListNode* currval = head; ListNode* prevval = NULL; while (currval != NULL && currval->next != NULL) { retval = currval == retval ? currval->next : retval; ListNode* nextIter = currval->next->next; currval->next->next = currval; if (prevval != NULL) { prevval->next = currval->next; } currval->next = nextIter; prevval = currval; currval = nextIter; } return retval; } };
實現3:
使用了一個pointer to pointer,非常巧妙
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode **pp = &head, *a, *b;
ListNode **pp2;
while ((a = *pp) && (b = a->next)) {
a->next = b->next;
b->next = a;
*pp = b;
ListNode *tmp = a->next;
pp2 = &tmp;
pp = &(a->next);
}
return head;
}
};
分情況解釋一下。
- 如果為空,或只有一個,返回的就是head;
- 不為空
- 一開始,pp指向head指標,
*pp=b
使得head發生了改變; - 再後來,pp指向的是前一個連結串列節點的next域,
*pp=b
完成了pre->next=pr
的工作。
- 一開始,pp指向head指標,