1 """
2 Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
3 To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
4 Note: Do not modify the linked list.
5 Example 1:
6 Input: head = [3,2,0,-4], pos = 1
7 Output: tail connects to node index 1
8 Explanation: There is a cycle in the linked list, where tail connects to the second node.
9 Example 2:
10 Input: head = [1,2], pos = 0
11 Output: tail connects to node index 0
12 Explanation: There is a cycle in the linked list, where tail connects to the first node.
13 Example 3:
14 Input: head = [1], pos = -1
15 Output: no cycle
16 Explanation: There is no cycle in the linked list.
17 """
18 """
19 判断链表是否有环。有两种做法
20 第一种是用set()存已经遍历过的结点
21 如果新的结点在set()里,则返回,有环
22 """
23
24 class ListNode:
25 def __init__(self, x):
26 self.val = x
27 self.next = None
28
29 class Solution:
30 def detectCycle(self, head):
31 nodes = set()
32 while head:
33 if head in nodes:
34 return head
35 nodes.add(head)
36 head = head.next
37 return None
38
39 """
40 解法二:快慢指针
41 A→B→C 快指针:A, C, B, D 一次走两步
42 ↖↓ 慢指针:A, B, C, D
43 D
44 根据距离推算:相遇点距环入口的距离 = (头节点距环入口的距离)*(快指针步数-1)
45 快慢指针相遇在D,让快指针变为head
46 同步向后,再次相遇即为环的起点
47 """
48
49 class ListNode:
50 def __init__(self, x):
51 self.val = x
52 self.next = None
53
54 class Solution:
55 def detectCycle(self, head):
56 if head == None or head.next == None:
57 return None
58 slow, fast = head, head
59 while fast:
60 slow = slow.next
61 fast = fast.next
62 if fast:
63 fast = fast.next
64 if fast == slow:
65 break
66 if slow != fast:
67 return None
68 fast = head #!!!关键所在
69 while slow:
70 if fast == slow:
71 return fast
72 fast = fast.next
73 slow = slow.next