142. 环形链表 II
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
示例 1:

1
2
3
| 输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点
|
示例 2:

1
2
3
| 输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
|
快慢指针 + 数学
slow 走一步,fast 走两步,一定会相遇
相遇后,建个 p 从头走,slow 继续走,相遇点即为第一个公共结点
证明详见:https://www.programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html#_142-%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8ii
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| func detectCycle(head *ListNode) *ListNode {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
for slow != head {
slow = slow.Next
head = head.Next
}
return head
}
}
return nil
}
|