[Go版]算法通关村第一关黄金——确定链表中是否有环,如果有环如何确定环的入口

文章介绍了如何使用快慢指针方法确定链表中是否存在环,并在存在环的情况下找到环的入口。通过快指针每次前进两步,慢指针前进一步,当两者相遇则证明有环;之后,再从头节点和相遇点同时出发,相遇点即为环的入口。文章提供了O(n)时间复杂度和O(1)空间复杂度的Go代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:确定链表中是否有环,如果有环如何确定环的入口

题目链接:LeetCode-142. 环形链表 II
在这里插入图片描述

思路分析:快慢指针+环的特点

  1. 如果存在环,让快慢指针从头开始跑,快的每次走2步,慢的每次走1步,他们一定会相遇(因为当快指针进入环之后,每轮移动fast与slow的距离都会缩小1,直至二者相遇)。
  2. 如果不存在环,那快指针会先到达链表末尾(fast.Next==nil)。
  3. 画图可以算出,从相遇点到环入口,和从链表头到环入口的距离是相等的,所以可以使用两指针同时同步走,相遇点即使环入口。

图示说明环的特点

在这里插入图片描述

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

Go代码

func detectCycle(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return nil
    }
    slow, fast := head, head
    find := false
    for fast != nil && fast.Next != nil {
        slow = slow.Next
        fast = fast.Next.Next
        if slow == fast {
            find = true
            break
        }
    }
    if !find {
        return nil
    }
    slow = head
    for {
        // 注意:这里要先判断,如果当前是个环形链表,则head就是入口,这里就能直接找到并退出了
        // 否则,会同时往下走一步,也是相等的,但其实不是入口
        if slow == fast {
            break
        }
        slow = slow.Next
        fast = fast.Next
    }
    return slow
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值