LeetCode Hot100刷题记录-142. 环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

思路:
在这里我们起初让slow = fast = head,而不是像环形链表1那样让fast = head.next,因为这里我们需要找到环形链表的入口处。
那么如何确定环的入口呢?
这个问题的核心在于:当快慢指针相遇后,如何找到环的入口?这里有个非常巧妙的思路:
假设从链表头到环入口的距离是 a,从环入口到相遇点的距离是 b,从相遇点绕回环入口的距离是 c。
如果快慢指针相遇时,我们把一个指针放回链表的头部,并且这次两个指针都每次走一步,它们最终会在环的入口处再次相遇。这个过程的推导稍微复杂一点,但你可以理解为当两个指针再次相遇时,它们刚好相遇在环的入口处。

var detectCycle = function(head) {
    if (!head || !head.next) return null;
    
    let slow = head;
    let fast = head;
    
    // 第一步:先判断是否存在环
    while (fast && fast.next) {
        slow = slow.next;
        fast = fast.next.next;
        
        if (slow === fast) {
            // 第二步:如果有环,找环的入口
            let p1 = head;
            let p2 = slow;
            
            // 两个指针同时每次前进一步,直到它们相遇
            while (p1 !== p2) {
                p1 = p1.next;
                p2 = p2.next;
            }
            
            // 返回环的入口节点
            return p1;
        }
    }
    
    // 如果没有环,返回 null
    return null;
};
posted @   一个甜橙子  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示