給定鏈表和整數k, 使用in-space方法將鏈表按k個爲一組進行倒序, 如果剩餘個數不足k個則保留其原始順序.
如給定1->2->3->4->5, k = 2, 需要返回 2->1->4->3->5; 給定1->2->3->4->5, k = 3, 需要返回 3->2->1->4->5.
算法描述:
- 使用指針cur遍歷鏈表;
- 使用指針pilot探索鏈表, 如果剩餘個數不夠, 跳出循環, 算法結束; 如果個數足夠, 則進行下一步;
- 只要指針cur和pilot沒有相遇, 就依次交換相鄰的node;
- 重新設置cur和pilot, 返回第2步.
需要說明的是第三步交換相鄰的node:
我們設需要交換的2個node分別爲cur和cur->next, 這裏用到2個指針: pre指向cur的前一個節點. 變換過程如下
ListNode *nt = cur->next->next;
nt保存後節點(需要交換的2節點之後的節點)信息.
cur->next->next = pre->next;
把第2個節點指向第1個節點(新方向).
pre->next = cur->next;
把前節點(需要交換的2節點之前的節點)指向第2個節點(重新構造開頭).
cur->next = nt;
把第1個節點指向後節點(重新構造結尾).
整理後, 兩個橘黃色節點已經對調, 並且兩者前後節點未變.
結束.
代碼:
1 class Solution {
2 public:
3 ListNode *reverseKGroup(ListNode *head, int k) {
4 if (head == NULL) return NULL;
5 ListNode *dummy = new ListNode(0);
6 dummy->next = head;
7 ListNode *pre = dummy;
8 ListNode *cur = head;
9 while(cur != NULL) {
10 ListNode *pilot = pre->next;
11 int remaining = k;
12 while (pilot != NULL && remaining-- > 0) pilot = pilot->next;
13 if (remaining > 0) break;
14 while(cur->next != pilot) {
15 ListNode *nt = cur->next->next;
16 cur->next->next = pre->next;
17 pre->next = cur->next;
18 cur->next = nt;
19 }
20 pre = cur;
21 cur = cur->next;
22 }
23 return dummy->next;
24 }
25 };