快慢指针基础进阶总结(证明为何快慢指针一定会相遇)

首先快慢指针是指 两个指针移动速度不一样,比如 fast 指针每次移动长度为2,slow 指针每次移动长度为 1 ,这样如果链表中存在环的话,fast 指针和 slow 指针一定会相遇

快慢指针可以解决什么问题?

  • 判断链表是否有环
  • 寻找链表的中点,(fast指针走到终点的时候,slow走到中点)
  • 寻找链表的倒数第k个节点 (设 fast = slow + k,fast 走到链表末尾时,slow走到倒数第k个节点)
  • 寻找链表的入环点 (先得到相遇指针,在让慢指针与相遇指针一起走,相遇的点就是入环点)
  • 求有环链表的环长 (第一次相遇后,让快慢指针继续跑,第二次相遇时,两者步数之差就为环长)

寻找链表的入环点

在这里插入图片描述

如图所示,如果链表中存在环,fast 指针和 slow 指针一定在环中相遇
这时
fast 指针走过的距离为: d i s ( f a s t ) = x + y + n ∗ ( y + z ) dis(fast) = x + y + n*(y + z) dis(fast)=x+y+n(y+z)
slow 指针走过的距离为: d i s ( f l o w ) = x + y dis(flow) = x + y dis(flow)=x+y由于 slow 指针走一步,fast 指针走 两步,所以 2 ∗ d i s ( s l o w ) = d i s ( f a s t ) 2 * dis(slow) = dis(fast) 2dis(slow)=dis(fast)
即: 2 ∗ ( x + y ) = x + y + n ∗ ( y + z ) 2 * (x + y) = x + y + n * (y + z) 2(x+y)=x+y+n(y+z)
化简得到:
x + y = n ∗ ( y + z ) x + y = n * (y + z) x+y=n(y+z)

等式成立的条件是:
x = z x = y + 2 z = z + ( y + z ) x = 2 y + 3 z = z + 2 ( y + z ) ⋯ x = n y + ( n + 1 ) z = z + n ( y + z ) \begin{aligned} & x=z \\ & x=y+2 z=z+(y+z) \\ & x=2 y+3 z=z+2(y+z) \\ & \cdots \\ & x=n y+(n+1) z=z+n(y+z)\end{aligned} x=zx=y+2z=z+(y+z)x=2y+3z=z+2(y+z)x=ny+(n+1)z=z+n(y+z)

(y + z)代表走一圈的距离

所以让 fast 指针和 slow 指针相交处的指针,绕环移动
那么这个指针走到入环点的距离是 z + n ( y + z ) z + n(y + z) z+n(y+z)
所以相遇指针和指向头节点的指针,同时开始移动,必然会在入环点相遇。

fast 指针每次移动 3 步是否可行? 4步,5步呢?

设 fast 指针每次走 k 步,环的长度为 s,并且 fast 指针和 slow 指针在第 n 圈的时候相遇,相遇点为 y

那么得到等式
k ∗ ( x + y ) = x + y + n ∗ s k * (x + y) = x + y + n * s k(x+y)=x+y+ns
化简得:
( k − 1 ) ∗ ( x + y ) = n ∗ s (k - 1) * (x + y) = n * s (k1)(x+y)=ns
将(y + z)除过去,得:

( x + y ) = n ∗ s k − 1 (x + y) = \dfrac{n * s }{k - 1} (x+y)=k1ns
其中 x,s 是确定的,变量 步长 k 和 相遇点 y ,和 圈数 n

证不出来,希望有那位佬可以帮忙从数学式子的角度证明一下

上另外一种好理解的证明方法:

假设,慢指针步长为 1,快指针步长为 k,环入口到链表起点距离为 x,环的长度为 s.

因为慢指针是一步一步走,所以可以遍历到链表中的每一个点,所以我们可以假设他们会相遇再任意一个节点

设 快慢指针 相遇点为 y 且 y 为 s 的整数倍,且 y > x; 那么 y 就表示 选取快慢指针相交的点。

那么此时快指针走过的距离为 ky,快慢指针的路径差为 (k - 1) * y; 因为 y 是 s 的整数倍,所以快慢指针肯定能遇见

根据上面的假设有式子:(k - 1)y = (k - 1)ns,s是确定的,n可以取满足 y 大于 x 的最小值,所以k - 1越小,相遇的越快,当 k = 2 时,有最小值

题目打卡

下面四道题中,前面两道可以用双指针来做,后面两道可以用快慢指针来做。

lc.24 两两交换链表中的节点

面试题 02.07 链表相交

lc.19 删除链表的倒数第N个节点

lc.142 环形链表 Ⅱ

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值