Reverse Nodes in k-Group

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. 两种方法对待:

  1. 要么我们一开始不check, 一路reverse, 直到最后一组leftovers 发现不够k个的时候, 我们再reverse回来. (实测这个方法速度更快) O(n+k)
  2. 我们每一组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;
        }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值