题解 | 链表中环的入口结点

链表中环的入口结点

https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4

还是使用快慢指针,为什么快慢指针能够找到环的入口节点,这里需要用到数学的推导

假设:

  • 从头节点到环入口的距离为 a
  • 从环入口到相遇点的距离为 b
  • 从相遇点走到环入口的距离为 c(即环的长度为 b + c)

在相遇时:

  • 慢指针走过的距离:s = a + b
  • 快指针走过的距离:f = a + n(b + c) + b (这里的 n 指的是在环内走了多少圈)

由于快指针的步幅是慢指针的2倍:

f = 2s => a + n(b + c) + b = 2(a + b)

即:

a = (n - 1)(b + c) + c

这意味着从头节点到环入口的距离 a,等于从相遇点绕环 n - 1 圈后再走距离 c。因此,一个指针从头节点开始,一个从相遇点开始,同步后移,一定会在环入口处相遇!

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if(pHead == null || pHead.next == null) return null;
        ListNode fast = pHead;
        ListNode slow = pHead;
        boolean hasCycle = false;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;

            if(fast == slow) {
                hasCycle = true;
                break;
            }
        }

        // 没有环,直接返回null
        if(!hasCycle) return null;

        // 快慢指针相遇后,慢指针重新指向头节点
        // 让快指针和慢指针同时移动1步,相遇时的节点即为入口节点
        slow = pHead;
        while(slow != fast) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

全部评论

相关推荐

牛客66512506...:那个百度acg是不是个小哥啊,老是问些底层问题狠狠为难,然后kpi
哪些公司在招寒假实习?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务