給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例 :
給定這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
你的算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
題解:
首先實現鏈表反轉函數。然後沒找到k個節點,進行反轉。
參考代碼:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* reverseKGroup(ListNode* head, int k) { 12 //特殊情況:NULL或僅有一個節點 13 if(head == nullptr || head->next == nullptr) 14 return head; 15 16 //虛擬頭結點 17 ListNode *dummyHead = new ListNode(0); 18 dummyHead->next = head; 19 20 //next指向當前結點的下一個結點 21 ListNode *next = head; 22 //pre_tail指向上一段鏈表的尾節點,初始值爲空指針 23 ListNode *pre_tail = nullptr; 24 //每一個段的頭結點 25 ListNode *newHead = head; 26 //計數值,當count增加到k時,就斷鏈,倒置,掛鏈 27 int count = 0; 28 29 while(head){ 30 count++; 31 next = head->next; 32 if(count == k){ 33 //斷鏈,並且將該小段鏈表送入倒置函數中 34 head->next = nullptr; 35 HeadTail headTail = reverse(newHead); 36 37 //掛鏈:處理倒置後的鏈表的頭和尾,巧妙利用pre初始值是否爲空 38 if(pre_tail) 39 //不爲空,則上一段鏈表尾節點指向新置鏈表頭結點 40 pre_tail->next = headTail.head; 41 else 42 //爲空,則虛擬頭結點指向新置鏈表頭結點 43 dummyHead->next = headTail.head; 44 45 headTail.tail->next = next; 46 47 //更新上一段鏈表的尾節點、下一段鏈表的頭結點和計數值count 48 pre_tail = headTail.tail; 49 newHead = next; 50 count = 0;//別忘記計數值重置 51 } 52 53 head = next; 54 } 55 return dummyHead->next;//dummyHead大法好 56 } 57 58 //鏈表的頭和尾結構體 59 struct HeadTail{ 60 ListNode *head; 61 ListNode *tail; 62 }; 63 64 //reverse函數返回兩個參數:倒置後的鏈表頭和尾 65 HeadTail reverse(ListNode* head){ 66 //巧妙使用pre指針,初始值爲空 67 ListNode *pre = nullptr; 68 ListNode *cur = head; 69 ListNode *next = head; 70 while(cur){ 71 next = cur->next; 72 //pre初始值爲空 73 cur->next = pre; 74 //更新pre值,很巧妙 75 pre = cur; 76 cur = next; 77 } 78 HeadTail headTail; 79 headTail.head = pre; 80 headTail.tail = head; 81 82 return headTail; 83 } 84 };