链表中很经常会出现的一个问题,判断链表是否有环,标准答案也已经烂熟于心,设置快慢指针,快指针每次走2步,慢指针每次走1步,如果两个指针可以相遇的话,证明链表有环,反之无环。

我有时候就犯嘀咕,它俩一定会相遇吗,难道就不存在一种可能,慢指针每次都被快指针跨过去,导致它俩始终不能相遇吗?然后,就在草稿上画图,确实是一定会相遇,再看看别人的总结,这个心魔总算是跨过去了。

但时间一久,就又忘记原因了,周而复始,黯然神伤。也不是一个特别难的问题,难道就不能用一种简单的思维来思考它吗?每次都得在小本本上哧啦哧啦画几下,写几个计算式,才能让自己心安理得下来?

可能存在快指针始终跨过慢指针吗

存在一种可能,在每次快慢指针距离最近的时候,快指针始终一步跨过慢指针吗?我们将可能存在的多种情况列举出来,这是标准的写代码思路,每个情况都单独处理,也是拆分的思路,将复杂问题拆解成简单的小问题。

第一种情况,当快指针距离慢指针只有1步的距离,那么,下次移动,快指针走2步,慢指针走1步,快慢指针相遇。
第二种情况,当快指针距离慢指针只有2步的距离,那么,再移动一次,就变成了第一种情况,最终还是会相遇。
第三种情况,当快指针距离慢指针只有3 步的距离,那么,再移动一次,就变成了第二种情况,最终还是会相遇。

以此类推,我们需要一个最终的推导公式来说明。假设快慢指针相差 N 步,那么下一次移动,快指针向前走2步,慢指针向前走1步,它们之间距离 N-1 步,快慢指针相距就会越来越近,最终最终快慢指针一定会相遇。

那为什么我们潜意识里会有它们可能永远不会相遇的这种错误想法呢?剖析我自己来说,如果是生活中的跑步问题,跑的快的在比跑的慢的多跑1圈之后,两个人一定会相遇。但转换成两个人同时在格子里向前跳,慢的和快的一定会相遇在同一个格子里,就让我很难理解。

从相对论的角度来看问题,快指针每次走2个格子,慢指针每次走1个格子,相当于慢指针不动,快指针每次都走1个格子,最终肯定是会站在同一个格子的。所以说,只要快慢指针只要在一个环里,快指针每次走2步,慢指针每次走1步,最终一定会相遇

相遇时慢指针一定走不够一圈吗

这些问题其实还挺烦人的,如果快慢指针同时出发,按照我们上面的逻辑推理,快指针一定只比慢指针多跑一圈(这是依据废话)。那看文章开头的图示,再链表的尾部,环的的结构中,
相遇的时刻,慢指针一定跑不够一圈吗?

有了上面的解释,因为快指针已经领先慢指针进入了环,等慢指针进入环之后,慢指针每次走1步,快指针和慢指针的间距缩短1步,最终慢指针一定跑不够一圈。结果确实是这样,但有没有数学过程可以证明呢?

还是这一幅图,假设在慢指针进入环的时候,快指针位于紫色的点,假设环的长度是l,则一定有 0<=b<l以及 0<=c<l,快指针每次走2步,慢指针每次走1步,在走了 t 步之后两者相遇。通俗的讲,快指针走过的距离减去慢指针走过的距离,等于慢指针没有走过的距离。简化成下面的推导过程:

快指针走了 2t 的距离
慢指针走了 1t 的距离
可以推导出:2t - 1t = c
最终得出结论:t = c
所以:0<=t<l,慢指针一定走不够一圈

我们可以做扩展延伸,假设快指针每次走f步,慢指针每次走1步,套用上面的计算过程,我们可以得出下面的表达式,当 f 等于 2 的时候,就是上述的结论。当 f 等于3时,t 等于 c/2,如果b为奇数,则不存在解。

t = c f − 1 t=\frac{c}{f-1} t=f−1c​

仍然在 f 等于 3 的情况下(快指针每次走3步),如果 c 为偶数,那么快慢指针会在t=c/2的时候相遇。

快慢指针判断链表是否有环相关推荐

  1. 使用快慢指针判断链表是否有环

    有时候在面试中可能会遇到叫我们判断链表中是否有环的问题,这个问题的解决方法也很多,这里我记录一下比较简单的使用快慢指针的方法: 使用快慢指针是指: 设置两个指针,一快一慢,快指的是每次移动两步,慢指针 ...

  2. 算法 --- 快慢指针判断链表是否有环

    解题思路: 分别设置2个指针(s,q)指向链表的头部,s每次指向下面一个(s = s.next),q每次指向下面2个(q = q.next.next). 如果存在环,q总会在某一时刻追上s /*** ...

  3. 快慢指针判断链表中是否存在环以及查找环的起始位置

    判断链表中是否有环?    使用快慢指针, 慢指针一次走一步, 快指针一次走两步, 当快慢指针相遇时,说明链表存在环 为什么快指针每次走两步而慢指针每次走一步呢?    因为slow指针和fast指针 ...

  4. 快慢指针判断链表中是否有环

    基本思想 快指针:从头开始移动 每次移动两个距离 慢指针:从头开始移动 每次移动一个距离 如果单链表中存在有环的话,那么快慢指针一定是会相遇的. 为什么?首先快指针在环内肯定是可以追上慢指针的对吧,那 ...

  5. 双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142

    一.简介:什么是快慢指针? 快慢指针,顾名思义,无非就是设置一个快指针,一个慢指针,初始化的时候,快指针和慢指针都指向链表的头结点,前进的时候一个在前一个在后,结合起来可以十分巧妙的解决链表中的一些问 ...

  6. 如何判断链表是否有环,确定环的起点

    如何判断链表是否有环,确定环的起点 目录 判断链表是否有环 如何找到环的入口 判断链表是否有环 使用快慢指针确定链表是否有环 快指针(fast) 慢指针(slow) 思路: 让快指针和慢指针从链表的起 ...

  7. 【刷算法】判断链表是否有环以及返回入环节点

    题目描述 判断一个单链表是否有环,有环则返回入环节点,否则返回null 1->2->3->4->5->6↑ ↓8<-7 复制代码 例如上面这个链表就有环,入环节点是 ...

  8. 数据结构:单链表操作之如何判断链表是否带环及相关操作

    //判断链表是否有环 int HasCircle(Node* pHead) { Node* low=pHead; Node* fast=pHead;     while(fast != NULL &a ...

  9. 面试题:判断链表是否存在环

    题目:判断链表是否存在环 思路:定义快慢指针,如果两个指针相遇则一定存在环. 1 public bool IsCircled(Node First) 2 { 3 if (First == null | ...

最新文章

  1. 【转】python 字符编码与解码——unicode、str和中文:UnicodeDecodeError: 'ascii' codec can't decode...
  2. c语言键盘回调函数键盘的码,深入浅出剖析C语言函数指针与回调函数(三)
  3. 用英语用计算机造句,英语造句用It’s adj (for sb) to do sth 造句10个
  4. mysql优化了解_了解MySQL如何优化
  5. ZBrush中如何实现智能对称
  6. PCL:RANSAC 空间直线拟合
  7. uniapp开发原生android插件,获取浏览器cookie
  8. 学习纹理格式(DXGI_FORMAT 和 VkFormat)
  9. 如何养成早起的好习惯?
  10. MATLAB求解矩阵特征值的六种方法
  11. three相机在模型上_threejs学习心得(场景的搭建+运动模型导入)
  12. MPC5744-LINFlexD
  13. 详解Unity中的粒子系统Particle System (十二 | 终)
  14. XINLINX VC707 的学习
  15. 研究生生涯的一些经验和感悟
  16. otg usb 定位_教你简单认识OTG与OTG线
  17. no applicable items eclipse
  18. POI2014 Salad Bar
  19. 使用 Oracle Enterprise Manager Cloud Control 12c 安装和管理 Oracle Data Guard
  20. 机器学习必会技能之微积分【一文到底】

热门文章

  1. ADA开发环境的建立
  2. 如何毁掉一个产品大佬
  3. 即时通讯软件(企业IM)对企业的作用
  4. java使用jxls导出excel功能
  5. java合成聚和例子_合成聚合原则(示例代码)
  6. 快速排序的三种划分算法
  7. 游戏五子棋(c语言)
  8. 招商银行-FinTech精英训练营初赛-编程题
  9. 什么是空实现?什么时候用空实现?
  10. 正则表达式 (?=) 正向先行断言