LeetCode0025.K个一组翻转链表 Go语言AC笔记

时间复杂度:O(n),空间复杂度:O(1)

解题思路

将一个长链表按照长度k分成若干段链表,然后对这若干段链表进行翻转,但是必须要保证这若干段链表顺序不能发生改变。为了保证每一段链表的顺序不变,就要让上一段已经翻转过的链表的尾结点的next指针指向当前段翻转后的头结点,并且当前段翻转后的尾结点的next指针要指向下一段未翻转的链表的头结点。

链表翻转用的是迭代法,方法可参考我之前写的题解:

LeetCode0206.反转链表 Go语言AC笔记https://blog.csdn.net/Hexa_H/article/details/127373893但是如果照搬上面翻转链表的代码,不便于实现每段链表的连接,所以我们要知道这段翻转链表的头结点的上一个结点和尾结点的下一个结点,这样在翻转链表后就可以通过这两个结点完成每段链表的连接。并且我们还要返回翻转后链表的尾结点,方便接下来的遍历过程。

在主函数中为方便起见创建一个虚拟头结点,然后让一指针遍历每个结点并计数,长度为k时就断开该结点与下一结点的连接,原因是为了翻转该段链表,直至遍历完所有结点。

AC代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseKGroup(head *ListNode, k int) *ListNode {
    tail:=head//当前段链表的尾结点
    length:=0//记录当前段链表的长度
    res:=&ListNode{Next:head}//虚拟头结点
    headPre:=res//上一段链表的尾结点
    for tail!=nil{
        length++
        if length==k{
            head=tail.Next//更新head为下一段链表的头结点
            tail.Next=nil//断开当前段链表与下一段链表的链接,为了反转当前段链表
            tail=reverse(headPre.Next,headPre,head)//更新尾结点为当前段反转后链表的尾结点
            headPre=tail//上一段链表的尾结点就是当前的尾结点
            length=0
        }
        tail=tail.Next
    }
    return res.Next
}

func reverse(head,headPre,nextHead *ListNode)*ListNode{
    newTail:=head//链表反转后的尾结点
    var pre *ListNode
    for head!=nil{
        next:=head.Next
        head.Next=pre
        pre=head
        head=next
    }
    headPre.Next=pre//令上一段链表与当前这段反转后的链表相连接
    newTail.Next=nextHead//当前这段反转后的链表与下一段链表相连接
    return newTail//返回的是当前段反转后的链表的尾结点
}

感悟

思路倒是有,但是写起来磕磕绊绊,一小时才AC,原因是忘记翻转链表前断开与下一段链表的连接了,每次都是超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SwithunH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值