题解 | #链表中环的入口结点#
链表中环的入口结点
https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4
数学原理:
v1 = x, v2 = 2x 相遇时s2 = 2*s1
假设起点到入口为 X,入口到相遇点为 Y,环长L。则有:s1 = X + Y; s2 = (X+Y)+L;
由于 s2 = 2s1,
所以 (X+Y)+ L = 2(X+Y),
那么,L = X+Y;
相遇点是 X+Y 处,也就是说,无论快慢指针只需要再走 X,就能走到环的起点处。因此,我们可以创造条件如下:
慢指针 low 从头开始走,走 X 的距离正好是环的起点,
快指针 fast 降到慢指针的速度继续往前走,走 X 的距离正好是环的起点,
这样,快慢指针以相同速度在起点处相遇,循环结束。同时,也找到了起点位置。
这里也说明,数学算法确实可以省钱(内存)~~~
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 head = pHead; // 初始化快慢指针 ListNode slow = head; ListNode fast = head; // 第一步:使用快慢指针检测是否有环 while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { // 第二步:找到环的入口 slow = head; while (slow != fast) { slow = slow.next; fast = fast.next; } return slow; // 环的入口节点 } } return null; } }