1. 来源
- LeetCode 141 - Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
- LeeCode 142 - Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return
null
.Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
2. 判断是否有环
双指针问题,设置两个指针 fast
和 slow
,初始均指向 head
节点。fast
指针每次走两步,slow
指针每次走一步。若 fast
指针或 fast.next
指针为 null,则无环;当 fast == slow
则有环。
3. 计算环的位置
假设环的连接点为 joint
,head
到 joint
的步长为 $x$,环长为 $L$, fast
和 slow
指针在交汇时经过了 $t$ 个步骤,交汇点 intersection
沿链表方向距离 joint
的步长为 $y$。则
$$
t=x+(L-y)\
2t=x+(L-y)+nL
$$
其中 $n$ 为交汇时 fast
指针已经在环上走过的圈数。可得:
$$
x=(n-1)L+y
$$
这个式子的含义是,head
到 joint
的距离,等于 intersection
到 joint
的距离加上环长的整数倍。
那么,让两个指针一个从 head
出发,一个从 intersection
出发,经过相同的步数(即 $x$)之后,他们应当在 joint
相汇。
LeetCode 142 Solution:
1 | public ListNode detectCycle(ListNode head) { |
4. 其他问题
- 怎么求环长?
fast
和 slow
交汇后,让 slow
再走一圈即得到环长。
或者先得到环的连接点,再从连接点开始走一圈环。
- 怎么得到单链表总长?
在计算环的连接点时,可以计算出 $x$,再加上环长。