一、核心思想
快慢指针(Floyd's Tortoise and Hare):两个指针从同一起点出发,快指针每次走两步,慢指针每次走一步。
- 如果存在环:快指针必然追上慢指针(两者在环内相遇)
- 如果无环:快指针先到达终点
Mermaid · 渲染中(下方为源码)
graph LR
A["1"] --> B["2"]
B --> C["3"]
C --> D["4"]
D --> E["5"]
E --> C
上图中,快慢指针从节点 1 出发,最终在环内相遇。
为什么一定能追上? 进入环后,快指针每步比慢指针多走 1 格,两者距离每步缩小 1,必然相遇。
二、LC 141:判断链表是否有环
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}复杂度:时间 O(n),空间 O(1)。
循环条件:fast != null && fast.next != null——快指针走两步,必须保证两步都有效。
三、LC 142:找到环的入口节点
3.1 数学推导
设:起点到环入口距离为 a,环入口到相遇点距离为 b,相遇点绕回环入口距离为 。