題目:25. K 個一組翻轉鏈表node
先看怎麼反轉鏈表(寫不出來的話,我建議你爪巴):函數
class Solution { public: ListNode* reverseList(ListNode* head) { if (head == nullptr) return nullptr; auto pre = head, cur = head->next; while (cur != nullptr) { auto next = cur->next; cur->next = pre; pre = cur, cur = next; } head->next = nullptr; return pre; } };
第一步,實現一個 K 個反轉的函數,把 [head, tail]
區間內的節點反轉(與上面的反轉鏈表一毛同樣),返回子鏈表的新的頭和尾。code
pair<ListNode*, ListNode*> helper(ListNode* const head, ListNode* const tail) { auto pre = head, cur = head->next; auto end = tail->next; while (cur != end) { auto next = cur->next; cur->next = pre; pre = cur, cur = next; } head->next = end; return {tail, head}; }
第二步,咱們先看看一個例子。leetcode
K = 3, list = [1 2 3 4 5 6] // 添加一個 dummy 節點 -1 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 // 變量指向 pre head tail next | | | | V V V V -1 1 -> 2 -> 3 4 -> 5 -> 6 // 執行 (head, tail) = helper(head, tail) 後 pre head tail next | | | | V V V V -1 3 -> 2 -> 1 4 -> 5 -> 6 // 從新「插入」子鏈表 pre head tail next | | | | V V V V -1 -> 3 -> 2 -> 1 -> 4 -> 5 -> 6 // 而後調整 [head, tail] 區間,繼續執行 helper pre head tail next | | | | V V V V -1 -> 3 -> 2 -> 1 -> 4 -> 5 -> 6 -> null
而後就能夠寫出主循環了:get
ListNode* reverseKGroup(ListNode* head, int k) { if (head == nullptr || head->next == nullptr) return head; ListNode *dummy = new ListNode(-1); dummy->next = head; auto pre = dummy; while (head != nullptr) { auto tail = pre; for (int i=0; i<k; i++) { tail = tail->next; // 若是不夠 K 個 if (tail == nullptr) return dummy->next; } auto next = tail->next; tie(head, tail) = helper(head, tail); // 「插入」子鏈表 pre->next = head, tail->next = next; // 區間移動 pre = tail, head = tail->next; } return dummy->next; }
👴 以爲這個常數空間的解法太陰間了,本身寫好多細節都會出問題,因此用棧試試。io
這下子代碼就好看得多了。class
class Solution { public: ListNode* reverseKGroup(ListNode* head, int k) { ListNode dummy(-1); auto cur = &dummy; auto p = head; while (p) { vector<ListNode*> buf; for (int i=0; i<k && p != nullptr; i++) buf.push_back(p), p = p->next; // 不足 K 個,直接連上後續的 if (buf.size() < k) { cur->next = buf[0]; break; } for (int i=buf.size()-1; i>=0; i--) cur->next = buf[i], cur = cur->next; // 防止出現環,e.g. k=2, list = [1, 2] cur->next = nullptr; } return dummy.next; } };