142. 环形链表 II

142. 环形链表 II

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

示例 1:

https://markdown-1303167219.cos.ap-shanghai.myqcloud.com/circularlinkedlist.png

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

示例 2:

https://markdown-1303167219.cos.ap-shanghai.myqcloud.com/circularlinkedlist_test2.png

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
}