快慢指针解决的环问题,看这一篇就够了

本篇为您解决以下几个问题

  1. 怎么判断一个链表有环?
  2. 怎么获得入环处?
  3. 怎么知道环大小?

进阶后方会附上证明

答案

一、怎么判断一个链表有环?

快慢指针如果相遇就有环

二、怎么获得入环处?

快慢指针相遇后,快指针回到链表头,而后和慢指针一样一次走一步,再次相遇时就是入环处

三、怎么知道环大小?

必须要入环处再走一圈才能得到环大小,并不是快慢指针第一次相遇时候的步数

进阶

演示

在这里插入图片描述

快慢指针相遇时链表结构如下图所示

在这里插入图片描述

名词解释

T : T a i l , 表 头 到 入 环 处 的 距 离 D : D i s t a n c e , 入 环 处 到 快 慢 指 针 相 遇 处 的 距 离 C : C i r c l e , 环 的 大 小 R : R e m i n d , 快 慢 指 针 相 遇 处 到 入 环 处 的 距 离 ( 顺 时 针 走 ) i : 快 慢 指 针 相 遇 时 快 指 针 环 内 走 过 的 圈 数 j : 快 慢 指 针 相 遇 时 慢 指 针 环 内 走 过 的 圈 数 k : 快 指 针 回 到 表 头 后 快 慢 指 针 一 起 走 , 慢 指 针 走 的 圈 数 S : 快 慢 指 针 相 遇 时 慢 指 针 环 内 走 过 的 步 数 n : i − j 快 慢 指 针 相 遇 时 快 慢 指 针 走 过 的 圈 数 的 差 \begin{aligned}&T:Tail,表头到入环处的距离\\&D:Distance,入环处到快慢指针相遇处的距离\\&C:Circle,环的大小\\&R:Remind,快慢指针相遇处到入环处的距离(顺时针走)\\&i:快慢指针相遇时快指针环内走过的圈数\\&j:快慢指针相遇时慢指针环内走过的圈数\\&k:快指针回到表头后快慢指针一起走,慢指针走的圈数\\&S:快慢指针相遇时慢指针环内走过的步数\\&n:i-j快慢指针相遇时快慢指针走过的圈数的差\end{aligned} TTailDDistanceCCircleRRemindijkSnij

假设

  • 不知道快慢指针各走了多少圈

一、证明为什么环就一定会相遇?

反证法,假设有个操场,你在刘翔后面跑,大家都不停,请问你会不会被超圈?

二、证明入环处是这样得到的正确性?

看相遇时候的步数

首先只看慢指针,慢指针的步数为 S = T + D + j C S=T+D+jC S=T+D+jC

然后看快指针,快指针的步数为 2 S = T + D + i C 2S=T+D+iC 2S=T+D+iC

两者相减为 S = ( i − j ) C = n C S=(i-j)C=nC S=(ij)C=nC

也就是说,相遇的时候,快指针正好超车 n n n

这个时候快指针回到起点处,慢指针继续走,看图

T T T步以后快指针从表头走了 T T T到达入环处,慢指针从表头走了 S + T S+T S+T步,慢指针比快指针多走了 S = n C S=nC S=nC,刚好 n n n圈,也就是说在入环处此时快慢指针相遇

三、证明环大小正确性?

入环处走了一圈回到入环处,当然是环大小了

四、环大小为什么不是 S S S

这个问题困扰我多年,先上结论:

因为 T T T不一定等于 R R R T = R + k C T=R+kC T=R+kC, k k k不一定 = 0 =0 =0

看到很多博客说,环大小就是第一次相遇时 S S S的大小,大错特错!
因为他们假设是第二次相遇时候,慢指针只走了 R R R的距离,就到达了入环处,实际情况是,慢指针可能走了 R + k C R+kC R+kC的距离才到达入环处!也就是说,慢指针走到了入环处的时候,又走了 k k k圈才等到快指针!

自己画图可以把 T T T设置大一点, C C C设置小一点就能看出来了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值