LeetCode0142.环形链表II Go语言AC笔记

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

解题思路

还是用快慢指针判断链表是否有环,但是如何确定环形链表的第一个结点呢?

首先将一个链表拆成三部分:

  1. x1:x1表示从链表的head到环形链表的入口结点的长度
  2. x2:x2表示从环形链表的入口结点到快慢指针第一次相遇结点的长度
  3. x3:x3表示快慢指针第一次相遇的结点到下一次到入口结点的长度

我们在小学都学过追击问题,快慢指针的速度差为1,所以当快慢指针第一次相遇时快指针刚好比慢指针多走了一个环形链表的长度。这样我们便可以在快慢指针第一次相遇时根据时间相同列出等式:

(x1+x2+x3+x2)/2=x1+x2

即x1=x3

而x3刚好是慢指针走到入口结点的距离,所以我们让快指针回到head每次走一步,慢指针照老样子继续走,当二者再次相遇时的结点就是我们要找的环形链表的入口结点。

AC代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func detectCycle(head *ListNode) *ListNode {
    slow,fast:=head,head
    for fast!=nil&&fast.Next!=nil{
        slow=slow.Next
        fast=fast.Next.Next
        if slow==fast{
            fast=head
            //下一次相遇的结点就是环形链表的第一个节点
            for slow!=fast{
                slow=slow.Next
                fast=fast.Next
            }
            return fast
        }
    }
    return nil
}

感悟

只能想到用哈希表记录遍历过的结点,以及用快慢指针的思路判断环,但是没有细细推敲快慢指针遍历时走过的长度关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SwithunH

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

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

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

打赏作者

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

抵扣说明:

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

余额充值