141:Linked List Cycle
142:Linked List Cycle II
使用快慢指针,无环的情况很容易,下面分析有环时的一些性质。
如下图所示,假设无环部分有x
个节点,有环部分有y
个节点。节点A
是从前往后扫描刚进入环的第一个节点。
判断是否有环
慢指针slow
,快指针fast
初始时刻都指向head
节点。slow
一次走一步,fast
一次走两步。
slow
走x
步第一次进入环指向A
,此时fast
一定在环内。- 有可能此时
fast
刚好也指向A
,可以立马判断有环。 - 若此时
fast
不指向A
,那么fast
落后slow
1 ~ (y-1)
个身位。fast
指向尾节点时落后1
个身位,指向A
的下一个节点时落后y-1
个身位。 fast
每次可以追上1
个身位,所以fast
第一次追上slow
时,slow
最多又继续走了y-1
步,也就是slow
不需要绕回A
节点就能判断有环。- 所以时间复杂度为
O(n)
。
返回节点A
- 假设
fast
第一次追上slow
时两个指针相遇在环内的T
节点。假设此时slow
走了x+z
步。
那么有x+z=k*y
。因为fast
等于是从head
开始走了x+z
步到达T
节点,然后又走了x+z
步绕回了T
节点。 - 第一次相遇后重新让
slow
指向head
,并且之后让slow
和fast
每次都只走1
步。经过x
步后slow
到达A
节点,可以证明此时fast
也刚好在A
节点。
fast
在T
节点时相当于从A
节点往后走了z
步,现在又走x
步,相当于从A
节点往后走x+z
步。在第一步中我们已经证明x+z=k*y
,所以此时fast
也刚好在A
节点。