Reverse Nodes in k-Group
Question:
思路:
又是一道很好的题, reverse link list的 hard 变形. 做完这个题感觉reverse link list的题型就能参透了
这道题呢要求根据给定的k值,来决定每隔几个node来一次reverse.
我一开始尝试运用一堆pointers, 做一个大while loop. 但是浪费很了很多时间, 最后也没能做出来. 原因之一是, 我没法在下一回合while loop 的时候仍然保存上一轮的head.
所以后来我放弃了,改用recursion, 事实证明 recursion是个很easy 的solution.
我们只要写一个helper function, 每一次function call 处理k个node. 接着每一次function 的 return 都return 回来这一组k个node reverse 完之后的head.
最后当剩下几个不够k个的node. 两种方法对待:
- 要么我们一开始不check, 一路reverse, 直到最后一组leftovers 发现不够k个的时候, 我们再reverse回来. (实测这个方法速度更快) O(n+k)
- 我们每一组reverse 都先check 够不够k个, 如果不够就直接reuturn head. 如果够k个,再recursion call reverse. (但是这种方法相当于走了两遍整个link list, 比方法一多走一遍) O(2n-k).
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
ListNode* prev;
ListNode* curr;
ListNode* temp;
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head) { return head;}
prev = NULL;
curr = head;
temp = head->next;
ListNode* new_head = reverse(curr, k);
if(new_head == head){
head->next = temp; // if k = 1, after reversing the head will be the same but pointing to NULL. so we need to point it back to original next.
return new_head;
}
head->next = reverseKGroup(curr, k);
return new_head;
}
ListNode* reverse(ListNode* head, int k){
for (int i = 0; i < k; ++i){
if(!curr) {
curr = prev;
prev = NULL;
return reverse(curr, i); // if left-out is not multiple of k, then we reverse it back, with the number of left-outs
}
ListNode* temp = curr;
curr = curr->next;
temp->next = prev;
prev = temp;
}
return prev;
}
};