力扣链表基础之环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

示例

1
2
3
4
5
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

思路

使用快慢指针法,分别定义fast和slow指针,从头节点出发,fast指针每次移动两个节点,slow重镇每次移动一个节点,如果fast指针和slow指针在途中相遇,说明这个链表有环。

随后从头节点出发一个指针,从相遇节点也出发一个指针,这两个指针每次直走一个节点,那么当这两个指针相遇的时候就是环形入口的节点。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func detectCycle(head *ListNode) *ListNode {
var slow, fast = head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if fast == slow {
// 从head出发
var index, index1 = fast, head
for index != index1 {
index = index.Next
index1 = index1.Next
}
return index
}
}
return nil
}