LeetCode #25 Reverse Nodes in k-Group

LeetCode #25 Reverse Nodes in k-Group

题目描述
给出一个单向链表,再给出一个常数k。
任务如下:
步骤一:讲单向链表前k个元素的顺序倒转
步骤二:剩下的元素重复执行步骤一、步骤二,直到剩下的元素不足k个。
要求:只允许使用常量级别的额外空间。

例子:
原链表:1->2->3->4->5
当k=2:2->1->4->3->5
当k=3:3->2->1->4->5

算法思路
我的算法是使用递归实现的。
首先,我们需要一个临时链表元素tmp,用于将两个链表元素反向。代码实现如下:

            tmp=now->next;
            now->next=tmp->next;
            tmp->next=now;

图示化如下:
纯手绘勿喷

可以注意到,这个过程是需要通过回溯才能完成的,也就是我一开头所说的递归了。

但是这样还不够,这样只能将k个翻转了,那这两个k-group之间要怎么连接呢?这就需要用到另一个额外变量链表元素tmpk

在链表往下链的过程中,我们需要一个计数器count,记录当前到了第几个链表元素。在回溯的过程中,count%k ==0,则说明这是一组k-group的最后一个元素,对这个元素的处理如下代码:

        if (tot%k==0)       //这里tot即count计数器
        {
            now->next=tmpk;
            tmpk=now;
        }

图示化如下:
渣手绘

完成这两步,基本就完成全部了,剩下的就是判断一下最后面不足k个的不需要翻转。
额外空间需求:2个ListNode变量:tmp tmpk,1个int变量 count,1个bool变量(用于判断最后不足k个)
时间复杂度:O(n)

存在的问题:我这个算法完全建立在递归回溯的基础上,如果链表元素过多,会导致栈空间不足。
我也思考了一下不用递归的做法,虽然还没想到怎么写,但时间复杂度应该是会变成O(kn),k为常量,而空间上应该也会用到更多的额外空间。最后从代码复杂度来说,应该也是更高的。

代码

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (head==NULL) return head;
        bb=false;
        tot=0;
        tmpk=head;
        dfs(head,k);
        return tmpk;
    }

private:
    bool bb;
    int tot;
    ListNode* tmpk;
    void dfs(ListNode*now,int k)
    {
        ListNode *tmp;
        tot++;
        if (now->next!=NULL) dfs(now->next,k);
        if (bb==false && tot%k==0)
        {
            bb=true;
            tmpk=now;
        }
        else if (tot%k==0)
        {
            now->next=tmpk;
            tmpk=now;
        }
        else if (bb && tot%k!=0)
        {
            tmp=now->next;
            now->next=tmp->next;
            tmp->next=now;
        }
        tot--;
        return;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值