提供一个python题解+简要的思路描述
环形链表->快慢指针
首先先确定是否有环-有的话快慢指针会重合,如果有环的话,再新启动一个从头访问的指针和慢指针相遇的地方就是入环点
假设环外的长度为a,快慢指针相遇的位置为距环入口点b的节点,快指针一定在慢指针第一次走环的过程中赶上慢指针,这时快指针已经走了n圈环了,假设环长度为c
根据以上描述得出-慢指针总共走过的距离为a+b,快指针的速度为慢指针的两倍,所以快指针走过的距离表示方式1为:2*(a+b),此外,根据快指针路径的特性得出快指针走过距离的表示方式2为:a+b+n*c
由此可以得到等式——2*(a+b)=a+b+n*c
得到a+b=n*c
对于慢指针要走到入环点需要走c-b步。如果需要和一个指针在入环点相遇,那么慢指针走到入环点的c-b步需要在环外完成,也就是从head开始在环外先走c-b步,剩下的a-(c-b)步对于慢指针而言就是在环内完成若干(k)个完整的圈
得到方程 a-(c-b)=k*c 化简得 a-c+b=k*c 即 a+b=(k+1)*c
所以需要在据入环点b处(快慢指针相遇的地方)开始一个从head遍历的指针和慢指针同步访问
(个人觉得k和n的关系没有那么显示,但是肯定可以不断绕环碰到一起,leetcode官方的题解中c是指环长-b)
附上python题解,纯纯官方题解-快慢指针的c++重构版
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self,head):
slow,fast=head,head
while fast is not None:
slow=slow.next
if fast.next is None:
return None
fast=fast.next.next
if fast == slow:
ptr=head
while ptr != slow:
ptr=ptr.next
slow=slow.next
return ptr
return None
def detectCycle1(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None or head.next is None:
return None
slow=head
fast=head.next
prev=head
while fast is not None:
if slow==fast:
# return prev
prev=head
while prev!=slow:
prev=prev.next
slow=slow.next
return prev
else:
# prev=slow
slow=slow.next
if fast.next is not None:
fast=fast.next.next
else:
return None
return None