- # Definition for singly-linked list.
- # class ListNode:
- # def __init__(self, x):
- # self.val = x
- # self.next = None
-
- class Solution:
- def detectCycle(self, head: ListNode) -> ListNode:
- fast, slow = head, head
- #让快慢指针一快一慢 快的追慢的 直至相遇
- while fast and fast.next:
- slow = slow.next
- fast = fast.next.next
- if slow == fast:
- #相遇时 用q记下此时相遇的节点位置 用p从首元节点开始跑
- p = head
- q = slow
- while p != q:
- #当二者相遇时,p和q所指的节点就是环的入口
- p = p.next
- q = q.next
- return p
- return None
该算法由数学计算可推导出: x = (n-1)(Y+Z) + Z
其中
x:首元节点到环入口的节点个数;
n:快指针在环内循环的圈数;
Y:环入口到快慢指针相遇点之间的节点个数:
Z:环中快慢指针相遇点到环入口之间的节点个数
关于为什么慢指针在环内循环不到一圈就能被快指针追上:
1.快指针肯定先于慢指针入环。
2.当慢指针入环时,快指针可在环中任意位置。
3.此时slow与fast之间的距离(从slow沿顺时针方向数到fast)记为i,环周长记为c。
4.fast追上slow(沿顺时针方向追)需要c-i次跳动,即slow移动c-i次被追上。
5.因为i>0 , 所以c-i < c i.e. slow在一圈内就会被fast追上。