Leetcode 142. 环形链表 II Linked List Cycle II - Python 双指针法

# 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追上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值