I,确定是否有环,没什么好说的,快慢指针法即可,若有环,快慢指针必再环内相遇,若无环,则快指针则先到尾部空指针。
class Solution:
def hasCycle(self, head: ListNode) -> bool:
'''
p_fast, p_slow = head, head
while p_fast and p_fast.next:
p_fast = p_fast.next.next
p_slow = p_slow.next
if p_fast == p_slow:
return True
return False
II,确定环的初始位置,则要先确定是否有环
有环时,设起点到环的初始节点距离为a(a未知),假设环的长度为b(b也未知)快慢指针在环内某一个节点相遇,此刻,快指针走的长度是慢指针的两倍
f=2s
f=s+nb 快慢指针都走过同样的a,快指针比慢指针多走了n倍的环的长度
f=2nb 由上面两个式子得到快慢指针都是走了环长度的倍数
s=nb
再一次,从头节点走到环的初始节点,可以走a步就到,也可以走a步加走完整个环再回到环初始节点,即a+nb步,现在已经慢指针已经走了nb步,则再走a步即可到环初始节点,但a是未知的,则现在设一个新的节点q从头结点开始与慢指针一起移动,则当q走到环初始节点时,走了a步,慢指针再走a步刚好也到环初始节点,二者相遇
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
low,fast=head,head
flag=0
while fast and fast.next:
low=low.next
fast=fast.next.next
if low==fast:
flag=1
break
if flag:
q=head
while q!=low:
q=q.next
low=low.next
return q
else:
return None