Skip to content

Commit 11b2f25

Browse files
authored
update
1 parent 3633f5d commit 11b2f25

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

142.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
class Solution(object):
2+
"""
3+
原理:首先初始化快指针 fast = head.next.next 和 slow = head.next,
4+
此时快指针走的路长为2, m慢指针走的路长为1,之后令快指针每次走两步,
5+
慢指针每次走一步,这样快指针走的路长始终是慢指针走的路长的两倍,
6+
若不存在环,直接返回None,
7+
若存在环,则 fast 与 slow 肯定会在若干步之后相遇;
8+
9+
性质1:
10+
设从head需要走 a 步到达环的入口,如果环存在的话,
11+
再走 b 步可以再次到达该入口(即环的长度为b),
12+
如果存在环的话,上述描述的 快指针 fast 和
13+
慢指针slow 必然会相遇,且此时slow走的路长
14+
小于 a + b(可以自行证明),设其为 a + x,
15+
当快慢指针相遇时,快指针已经至少走完一圈环了,
16+
不妨设相遇时走了完整的m圈(m >= 1),有:
17+
18+
快指针走的路长为 a + mb + x
19+
慢指针走的路长为 a + x
20+
21+
由于快指针fast 走的路长始终是慢指针的 2倍,所以:
22+
23+
a + mb + x = 2(a + x)
24+
25+
化简可得:
26+
27+
a = mb - x ------------- (*)
28+
29+
当快指针与慢指针相遇时,由于 <性质1> 的存在,
30+
可以在链表的开头初始化一个新的指针,
31+
称其为 detection, 此时 detection 距离环的入口的距离为 a,
32+
33+
此时令 detection 和 fast 每次走一步,
34+
会发现当各自走了 a 步之后,两个指针同时到达了环的入口,理由分别如下:
35+
36+
detection不用说了,走了a步肯定到刚好到入口
37+
fast已经走过的距离为 a + mb + x,当再走 a 步之后,
38+
fast走过的总距离为 2a + mb + x,带入性质1的(*)式可得:
39+
2a + mb + x = a + 2mb,会发现,fast此时刚好走完了
40+
整整 2m 圈环,正好处于入口的位置。
41+
42+
基于此,我们可以进行循环,直到 detection 和
43+
fast 指向同一个对象,此时指向的对象恰好为环的入口。
44+
45+
"""
46+
47+
def detectCycle(self, head):
48+
"""
49+
:type head: ListNode
50+
:rtype: ListNode
51+
"""
52+
# 首先初始化快指针和慢指针,确保快指针走的路的长度是慢指针长度的2倍
53+
if head and head.next:
54+
fast = head.next.next
55+
slow = head.next
56+
else:
57+
return None # 说明无环
58+
59+
# 进行循环,首先让快指针和慢指针第一次相遇
60+
while fast:
61+
if fast != slow:
62+
63+
# 快指针走两步
64+
if fast.next:
65+
fast = fast.next.next
66+
else:
67+
return None # 说明无环
68+
69+
# 慢指针走一步
70+
slow = slow.next
71+
else:
72+
detection = head
73+
while detection != slow: # 此时由于slow和fast是一样的,用哪个都行
74+
slow = slow.next
75+
detection = detection.next
76+
77+
return detection
78+
79+
'''
80+
题:
81+
输入:head = [3,2,0,-4], pos = 1
82+
输出:true
83+
解释:链表中有一个环,其尾部连接到第二个节点。
84+
85+
注: 不允许修改给出的链表
86+
87+
解:
88+
快慢指针
89+
'''

0 commit comments

Comments
 (0)