经典链表算法题:找到环的入口。清晰图示推导出来

在这里插入图片描述

Leetcode题目链接

原理

重画链表如下所示,线上有若干个节点。记蓝色慢指针为 slow,红色快指针为 fast。初始时 slow 和 fast 均在头节点处。
0208_2.png
使 slow 和 fast 同时前进,fast 的速度是 slow 的两倍。当 slow 抵达环的入口处时,如下所示。
0208_3.png
其中:

  • head 和 A 的距离为 z z z
  • 弧 AB (沿箭头方向) 的长度为 x x x
  • 同理,弧 BA 的长度为 y y y

可得:

  • slow 走过的步数为 z z z
  • 设 fast 已经走过了 k k k 个环, k ≥ 0 k \geq 0 k0,对应的步数为 z + k ( x + y ) + x z + k(x+y) + x z+k(x+y)+x

以上两个步数中,后者为前者的两倍,整理可得 z = x + k ( x + y ) z = x + k(x+y) z=x+k(x+y),替换如下所示。
0208_4.png
此时因为 fast 比 slow 快 1 个单位的速度,且弧 BA 的长度为整数,所以再经过 y 个单位的时间即可追上 slow。

即 slow 再走 y y y 步,fast 再走 2 y 2y 2y 步。设相遇在 C 点,位置如下所示,可得弧 AC 长度为 y。
0208_5.png
因为此前 x + y x + y x+y 为环长,所以弧 CA 的长度为 x x x
此时我们另用一橙色指针 ptr (pointer) 指向 head,如下所示。并使 ptr 和 slow 保持 1 个单位的速度前进,在经过 z = x + k ( x + y ) z = x + k(x+y) z=x+k(x+y) 步后,可在 A 处相遇。
0208_6.png
再考虑链表无环的情况,fast 在追到 slow 之前就会指向空节点,退出循环即可。

算法实现

Screenshot 2024-05-12 at 7.52.17 PM.png

复杂度

时间: Θ ( n ) \Theta(n) Θ(n)

  • 如果相交
    • fast 和 slow 相遇时 slow 走过的距离 ≤ n \leq n n,所以 fast 走过的距离 ≤ 2 n \leq 2n 2n
    • ptr 走过的距离 < n < n <n
    • slow 走过的距离 ≥ n \geq n n < < < fast 和 ptr 走过的距离之和。
  • 如果不相交,fast 走过 n n n 步即结束

空间: Θ ( 1 ) \Theta(1) Θ(1)

推广

以下皆为个人所著,兼顾了职场面试和本硕阶段的学术考试。

点赞关注不迷路,祝各位早日上岸,飞黄腾达!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值