目录

一、如何判断一个链表是否有环?

二、如何证明fast和slow不会在回环中错过,永远都遇不上?

三、为什么slow走1步,fast走的是2步?能不能fast一次走3或者n步?

(1)fast走3步,slow走1步的情况。

(2)fast走4步,slow走1步的情况。

总结:

四、如何求链表回环的入口节点

刷题:


一、如何判断一个链表是否有环

A:数据结构中的链表入门必学的一种线性结构,那单向链表带环是什么呢?

B:老师又来考我了,这不是送分题吗?单向链表中的一个节点的指针指向之前的节点,形成闭环就是链表带环。

A:那如何判断一个链表是否有环

B:简单,用快慢指针。先定义两个指向该链表类型的指针,为了方便理解,一个叫fast,一个叫slow。让slow指针一次走1步,让fast指针一次走2步。通过判断fast是否为空,来决定循环是否继续。如此,只会存在两种情况。当fast不为空,只需要在每次行动后判断fast和slow指向的地址是否相同,就可以判断有没有带环。如果fast和slow指向地址相同,说明链表带环(因为只有存在回环,才能让同起点出发且速度更快的fast指针和slow指针相遇);当fast为空,说明该链表没有形成闭环,没有带环。

二、如何证明fast和slow不会在回环中错过,永远都遇不上?

A:那如何证明fast和slow不会在回环中错过,永远都遇不上?

B:好问题,让我想想。。。。。。

B:为什么呢?我好像明白这样是可以的,但是要怎么证明?

A:那就让我来讲解为什么slow指针走一步,fast指针走两步在在回环中不会错过且一定可以遇上。

第一步:fast和slow指针从链表的第一个节点开始走,fast一次走两步,slow一次走一步。

第二步:fast速度是slow的一倍,如果链表不带环,fast肯定会先到链表末尾。如果链表带环,fast会比slow先进入回环。

第三步:slow在fast之后进回环,且一定经过会在入环点。当slow在入环点时,fast和slow会相差一段距离,假设距离为N步。

第四步:fast每次都会比slow多走一步。从相对运动的角度来看,slow对于fast来说每次都会更接近一步的距离。从slow入环时,fast和slow相距N步,到每一次循环距离都会减1。作为正整数的N肯定会被减到0,因此,fast肯定会与slow相遇且不会错过。

B:对对对,我就是怎么想的,就是说不上来。

三、为什么slow走1步,fast走的是2步?能不能fast一次走3或者n步?

A:那为什么slow走1步,fast走的是2步?能不能fast一次走3或者n步?(n为比3大的正整数)

B:老师我懂了。我认为如果fast不是2步,会出问题。

(1)fast走3步,slow走1步的情况。

第一步:fast和slow指针从链表的第一个节点开始走,fast一次走3步,slow一次走1步。

第二步:fast速度比slow快。如果链表不带环,fast肯定会先到链表末尾。如果链表带环,fast会比slow先进入回环。

第三步:slow在fast之后进回环,且一定经过会在入环点。当slow在入环点时,fast和slow会相差一段距离,假设距离为N步。

第四步:fast每次都会比slow多走2步。从相对运动的角度来看,slow对于fast来说每次距离都会减少2步。但是,当fast快要接近slow时会出现两种情况。第一种是fast和slow距离为0,两者相遇。第二种是fast和slow距离差1,当fast下一次行动时就会和slow错过,fast和slow的距离就是K-1。(K为链表回环的节点个数)如果K为偶数,K-1就是奇数。说明fast和slow距离相差次数不可能被2减为0。因此fast每次都会和slow错过。如果K为奇数,K-1就是偶数。那么fast和slow的距离是可以被2减为0的,fast会和slow相遇。

下面总结fast走3步,slow走1步有两种情况会遇上:(1)当slow指针进入圆环时,fast和slow相距距离为偶数(2)链表回环中的节点个数为奇数

(2)fast走4步,slow走1步的情况。

第一步:fast和slow指针从链表的第一个节点开始走,fast一次走4步,slow一次走1步。

第二步:fast速度比slow快。如果链表不带环,fast肯定会先到链表末尾。如果链表带环,fast会比slow先进入回环。

第三步:slow在fast之后进回环,且一定经过会在入环点。当slow在入环点时,fast和slow会相差一段距离,假设距离为N步。

第四步:fast每次都会比slow多走3步。从相对运动的角度来看,slow对于fast来说每次距离都会减少3步。当fast快要接近slow时会出现下面这种情况。

当fast和slow距离差1,当fast下一次行动时就会和slow错过,fast和slow的距离就是K-1。(K为链表回环的节点个数)当fast第二次接近slow时,他们之间的距离会差2,当fast下一次行动时就会和slow错过,fast和slow的距离就是K-2。当fast第三次接近slow时,他们之间的距离会差3,当fast下一次行动时就会和slow相遇,fast和slow的距离就是0。

可以看出,fast走4步,slow走1步会出现每3次fast靠近slow,只有1次相遇,其他两次都错过。

总结:

当slow走1步,fast得走n步。n为偶数,fast和slow一定相遇。n为奇数,fast和slow可能会相遇。n为3到3以上的步数一定会存在fast与slow错过的情况,且偶数的n越大,在fast接近slow的次数相同时,错过的概率就越大。n为奇数视情况而定,主要分析slow在入环点时,fast和slow的距离N,和fast与slow第一次错过的距离K。

四、如何求链表回环的入口节点

根据先前分析,我们知道了fast指针走2步,slow指针走1步一定会在回环中相遇。由此当fast和slow第一次在回环中相遇时,我们可以得到以下信息,为了方便理解,我们通过图的方式,展现各个数值的具体意义。

fast和slow在回环中第一次相遇时,fast在回环中走过n圈(n最小为1),slow不可能在回环中走过1圈(不明白可以看上一篇文章)。因此,假设slow从回环入口节点处走C步时,便会与fast相遇。可以得到slow走了X+C步,fast走了X+C+nK步(K表示回环一圈的步数)。由于fast走的步数是slow的一倍,所以2(X+C) = X+C+nK。

简化式子:(X+C) = nK

我们需要求得是回环入口节点的位置,所以需要得到的是X等于什么?

根据需求,我们可以将式子转换为:X = nK-C

上式中可以得到从链表头走到回环入口节点需要从相遇点走n圈减C的路程(n圈减C的路程也就是在相遇点位置走到回环入口的步数加n-1圈的步数)。

简而言之,只需要在fast和slow第一次相遇时,记录相遇点的位置。从相遇点走X步就会到达回环入口节点,X步数是链表头到相遇点的距离。两者走相同步数到达的同一地点,就是相遇点的位置。

刷题:

需要动手实践的小伙伴可以点后面的链接进入力扣的环形链表II(力扣)

下面是验证代码和力扣刷题图片:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *fast = head;struct ListNode *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow){struct ListNode *meet = fast;struct ListNode *ret = head;while(meet != ret){meet = meet->next;ret = ret->next;}return meet;}}return NULL;
}

如有不当之处,感谢各位大佬指正。

数据结构-链表带环问题相关推荐

  1. 数据结构实验--带环、相交链表问题

    一.问题描述: 基于课程上机关于单链表的作业,要求进一步实现以下需求: 1.构造链表后,将元素值为 m 和 n(从键盘输入,如有多个相同元素值,仅考虑首个出现的元素)的节点建立连接,注意判断节点出现的 ...

  2. 链表带环问题(LeetCode 142)

    目录 记录算法思路 分析题目 1. 判断链表是否带环 2.链表所带环的起始位置 总结 记录算法思路 在LeetCode上做到了一个有意思的题,思路非常有意思,记录如下 原题链接 环形链表Ⅱ 分析题目 ...

  3. c/c++单链表面试题—链表带环问题

    1.判断一个单链表是否带环 思路解析: 判断一个单链表是不是带环,就看在遍历单链表的时候能不能遍历完成,如果带环的话会陷入死循环程序一直无法结束,但是这种判断方法在程序的实现是不可能的.所以转换一种思 ...

  4. 链表带环问题及相遇点问题

    带环问题 基本思路: 快慢指针,慢指针走一步,快指针走两步,如果链表带环,则快指针先进入环内,并且两节点必在环内相遇. 扩展问题: 当快指针一次性走3,4...,n步是否可以. 假设指针内环为两个结点 ...

  5. 数据结构--链表--约瑟夫环问题(单向循环链表)

    问题:一群人站成一个圆圈,从一个人开始报数,1, 2 ,...m,报到m的拉出去砍了,求被砍的顺序和最后一个活下来的. 利用单向循环链表实现 C++代码如下:(参考书籍:数据结构与算法实验指导书) # ...

  6. 数据结构-链表3-循环链表

    LinkList.h #ifndef LINKLIST_H #define LINKLIST_H #define _CRT_SECURE_NO_WARNINGS #include<stdlib. ...

  7. 链表带环问题(详解)

  8. 【神秘海域】[动图] 结合题目-手把手带你剖析 “带环链表”

    文章目录 引言 带环单链表之前 : 快慢指针 题1:单链表的中间结点 题2:链表中倒数最后k个结点 带环链表分析 题:环形链表 带环链表的问题 ⭐带环链表深入分析⭐ * 问题1 问题2 问题3 题:寻 ...

  9. 数据结构——链表经典OJ题题解

    前言 在学习了单链表这种数据结构后,便可以尝试去练习一些题目来巩固对这块知识点.练习这些题目还可以让我们提升代码能力和对指针有新的理解. 1. 移除链表元素 方法一 思路 通过两个指针变量来遍历整个链 ...

最新文章

  1. WEB安全,SQL注入漏洞的加固代码汇总
  2. 不用卷积,也能生成清晰图像!Transformer再下一城
  3. 分布式消息系统Kafka初步
  4. HYSBZ/BZOJ 1038 [ZJOI2008] 瞭望塔 - 计算几何
  5. 96秒100亿!如何抗住双11高并发流量?
  6. Linux搭建深度学习环境使用指南
  7. 如何利用SQL Server的事务日志?
  8. android 图片墙拼贴,三步搞定 用APP打造图片文字拼贴效果
  9. 阿里云MaxCompute中pyODPS的使用:多线程上传、下载、分区
  10. 单机到集群的WEB架构演变
  11. 网页设计软件列表HTML,【网站设计用什么软件】网页设计软件具体有哪些,常见的十种网页设计软件介绍!...
  12. 海康球机3D定位功能编码实现VC(对前一篇补充改进)
  13. 基于Java基础的客户信息管理系统
  14. 360校招笔试题总结4
  15. c语言第十章函数课后作业,c语言函数练习题附答案.doc
  16. 计算机加内存还是固态硬盘,电脑慢加内存还是固态硬盘好
  17. 天池竞赛-金融风控-task1
  18. h0043. 奇怪的汉诺塔
  19. 计算机英语期末考试方案,【计算机英语论文】计算机实训考核方法改革方案(共4649字)...
  20. java发送会议邀请邮件模板_使用java发送每封电子邮件的日历邀请

热门文章

  1. 选型宝访谈:如何借助API生态平台,一站式快速搞定APP开发?
  2. OpenCV-Python学习(8)—— OpenCV 颜色表操作(cv.LUT、cv.applyColorMap)
  3. 诛仙符详细介绍 - 诛仙 诛仙符
  4. 连接mysql数据库字符串_MySQL数据库中怎么将字符串连接操作
  5. 简单易懂的特征值与特征向量
  6. Unity自定义日志系统
  7. python语言第11天笔记
  8. 实战CenterNet,训练猫脸关键点检测数据集并测试
  9. 回收站的文件删除了还能恢复吗?
  10. Apache Jmeter 教程