如果有环,那么一快(2步)一慢(1步),总会在环的某个位置相遇,这个时候,快指针比慢指针多走了n圈,因为快指针可能走了很多圈,慢指针还没进圈。设环的长度为b,则有f = 2s,f = s+nb,s = nb
另外,指针从开始走到入口,需要的步数假设是a,以后每次再到达入口走的次数是a+nb
。
现在慢指针已经走了nb步了,再走a步即可再次到达入口处,因此需要一个让慢指针走a步的控制方法。
我们再设一指针,让其从开始走到入口,同时慢指针也继续走就能同时到入口处了。
代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersect(self, head):
#这个函数负责寻找,快慢指针第一次相遇的位置
tortoise = head
hare = head
while hare is not None and hare.next is not None:
tortoise = tortoise.next
hare = hare.next.next
if tortoise == hare:
return tortoise
return None
def detectCycle(self, head):
if head is None:
return None
intersect = self.getIntersect(head)
if intersect is None:
return None
#如果有环的话,就把新的节点设在头部,和原来相遇的节点每次向前走一步,相遇的地方就是环的入口
ptr1 = head
ptr2 = intersect
while ptr1 != ptr2:
ptr1 = ptr1.next
ptr2 = ptr2.next
return ptr1