Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
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.
Note: Do not modify the linked list.
Example 1:
1 | Input: head = [3,2,0,-4], pos = 1 |
Example 2:
1 | Input: head = [1,2], pos = 0 |
Example 3:
1 | Input: head = [1], pos = -1 |
解法1
双指针,快指针在前,慢指针在后.快指针一次走两步,慢指针一次走一步.如果链表无环,快指针一定先达到链表尾.否则,快指针比满指针走的快,快指针和慢指针一定会在链表上相遇.
找到快慢指针相遇的环中节点后,接下来要怎么找入环节点呢.我们知道快指针比慢指针快,如果要是能让快指针和慢指针在入环节点处相遇,那么需要快指针比慢指针多走一个环的长度的距离.当快指针和慢指针都在环上走时, 如果让慢指针先出发,当快指针赶上慢指针时,快指针正好比慢指针多走了一个环长的距离.所以,只需要让慢指针先走一个环的长度的距离,然后快指针和慢指针一起走,快指针来追赶慢指针,当慢指针赶上快指针时,正好是在入环节点上.
那么如何求环的长度呢?只需要一个指针从(快慢指针在环上相遇的节点)相遇节点出发, 再次回到该节点所需要走的步数就是环的长度.
为什么必须快指针在前,慢指针在呢?举个例子
如果链表是1->2->3.
如果初始化时,慢指针在前,指向节点2, 快指针在后,指向1,那么快指针会赶上慢指针,即快慢指针会在节点3相遇,那么结束条件就不能是快指针和慢指针是否相遇.如果如上所示,即使没环,快慢指针也会在节点3处相遇.