141环形链表


题意: 给定一个链表,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

返回值:如果链表中存在环,则返回 true 。 否则,返回 false 。

说明:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

思路:

这道题目,主要考察对链表的操作。

主要方法:
双指针:快慢指针


双指针:快慢指针

变量:首先定义 fastslow 快慢指针。

操作:从头结点出发,fast指针每次移动两个结点,slow指针每次移动一个结点。如果fast和slow指针在途中相遇,说明这个链表有环返回true。如果fast最后走到了空结点,说明这个链表没有环返回false。

为什么fast一次走两个结点,slow一次走一个结点,如果有环的话,一定会在环内相遇呢,而不会永远的错开?

首先明确一点:如果有环,fast指针一定是先入环,slow指针后入环,如果要相遇那么一定会在环内相遇。fast指针一定会在slow指针的前面。

其次:为什么fast指针和slow指针一定会相遇呢?

我们知道 fast 指针一次移动两个结点,slow指针一次移动一个结点。fast 指针相对于 slow 指针每次移动一个结点,然后又是在环内,fast 又在 slow 的 前 面,就相当于fast在slow后面追赶slow,每次向slow靠近一步。所以最后一定就会把slow指针追上。

最终情况,如下图:



思考问题:

slow指针在环内走过的结点会不会超过一圈?

请看极限情况,fast和slow的相差距离为C-1。如下图。



设环的长度为 C 时,考虑极限最大情况下fast和slow指针相差C-1个结点。当在slow指针进入环后,设fast指针走了Y的长度,slow指针走了X的长度,所以有等式 Y-X=C-1, Y=2*X, ==> X = C-1。所以在极限情况下慢指针进入环内最多在环中走了C-1个结点,所以不会超过一圈。


fast 指针在环内走过的结点最少是多少呢?

请看极限情况,fast和slow的相差距离为0时。如下图。



设环的长度为 C 时,考虑极限最小情况下fast和slow指针相差0个结点,即慢指针刚刚进入环就遇见快指针。当在slow指针进入环后,设fast指针走了Y的长度,slow指针走了X的长度,所以有等式 Y-X=0, Y=2*X, ==> Y= 0。但是之前快指针最少已经走了C个节点,因此快指针进入环后相遇慢指针最少走了C个节点。


fast 指针为什么要一次走两个节点,一次走三步节点,一次走四个节点,最终还会不会和slow指针相遇呢?

答案是:可能会相遇,当快指针走三步时,快指针就相对于慢指针走2步,当最后慢指针和快指针刚刚相差一个节点时,这时快指针就刚刚跨过慢指针,所以这次就不会相遇了。走四步也是一样的。所以当快指针走两步时,就一定会相遇,因为快指针只相对于慢指针走一步,每次靠近一步,所以最后一定会相遇慢指针。


C++代码

class Solution {public:bool hasCycle(ListNode *head) {if(head==nullptr||head->next==nullptr)return false;ListNode *fast=head;ListNode *slow=head;while(fast->next&&fast->next->next){fast=fast->next->next;slow=slow->next;if(slow==fast){ //一定要在移动了再判断。找到了直接返回truereturn true;}}return false; //说明没有环 fast走到了链表最后的空指针}
};

142. 环形链表 II

题意: 给定一个链表,返回链表开始入环的第一个结点。如果链表无环,则返回null。为了表示给定链表中的环,使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如果 pos 是 -1,则在链表中没有环

返回值:如果链表中存在环,则入环的第一个结点 。 否则,返回 null 。

说明: 不允许修改给定的链表。

思路:

1.这道题目,主要考察对链表的操作。2.还有数学的相关运算

主要方法:
双指针:快慢指针,判断链表是否有环
找到环之后怎么样找第一个入口,以及怎么证明。


双指针:快慢指针,判断是否有环

对于这个我在上面已经给出了相应的解释和方法了,相信大家都能看懂。

找到环之后怎么样找第一个入口,以及怎么证明。

当我们能够判断链表有环时,这下我们的目的就是怎样找到环的入口结点了。



变量:假设头节点到环的第一个入口节点的节点数为X。环形入口结点到fast指针和slow指针相遇节点 节点数为Y。环的节点数为C。那么相遇节点到环第一个入口节点的节点数为 C-Y

证明:
相遇时慢指针走过的节点数为X+Y:我在上面已经给出了证明慢指针在环内走过的节点数不会超过一圈。所以慢指针在环中走过的长度就是Y.
相遇时快指针走过的节点数为X+NC+Y(N>=1):我们不知道环的大小,当环很小时,快指针可能在环内已经走了很多圈了。
相遇时有等式 X+NC+Y = 2(X+Y):因为快指针是慢指针速度的两倍。解得等式有 X = NC-Y==>X = (N-1)C+C-Y。
最后推出来的等式说明:从头节点出发一个指针,从相遇节点出发一个指针,这两个指针每次走一步,那么当这两个指针相遇时就是环形入口的节点。因为当N=1时,等式刚刚是X = C-Y,所以刚好相遇时就是环形入口节点。当N>1时,也能找到相遇节点,如果N>1就是一个指针在环内多绕 N-1 圈最后还是找到了环形的入口节点。

C++代码

class Solution {public:ListNode *detectCycle(ListNode *head) {ListNode *fast=head;ListNode *slow=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(slow==fast){   //相遇说明有环while(head!=slow){ slow=slow->next;head=head->next;}return head;}}return nullptr;}
};

链表:判断链表是否有环以及找入口相关推荐

  1. LeetCode141. 环形链表判断链表是否有环

    题目要求 原题目链接:141. 环形链表 题目要求如下: 给你一个链表的头节点 head ,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了 ...

  2. 链表--判断链表中是否有环

    题目: 判断给定的链表中是否有环.如果有环则返回true,否则返回false. 数据范围:链表长度 0≤n≤10000,链表中任意节点的值满足 ∣val∣<=100000 要求:空间复杂度 O( ...

  3. 《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明

    先看看原题:<编程之美>3.6编程判断两个链表是否相交,原题假设两个链表不带环. 注:位于(*)符号之间的文字出自于:http://blog.csdn.net/v_july_v/artic ...

  4. 快慢指针判断单向链表是否有环及找环入口

    前言 关于快慢指针找环入口的这个问题,之前巴特跟我聊到过,印象比较深,今晚看学长在做的面试题,里面就出现了这个小知识. 发现有些东西不经意间就会用到,于是便出现此文.以后要努力做到善于总结,乐于总结. ...

  5. 判断链表是否有环,并且找出链表环的接点

    1.判断链表是否有环,根据Floyd判圈法,设置两个指针,fast, slow.fast指针每次移动2个位置,slow指针每次移动1个位置.如果链表有环,fast,slow指针会再次相遇. 2.如果链 ...

  6. fatal error lnk1561: 必须定义入口点_链表中是否有环以及找环的入口问题总结

    这篇会详细介绍有关环的入口节点问题,包括代码和理论证明. 首先来看一下如何判断链表中是否存在环.方法很简单,定义两个快慢指针slow和fast,慢指针每次走一步,快指针每次走两步,如果存在环,则快慢指 ...

  7. 漫画算法:如何判断链表有环?

    大四毕业前夕,计算机学院, 正在四处求职的小灰碰到了同系的学霸大黄...... 小灰边说边回忆着上周去面试的情形...... 有一个单向链表,链表当中有可能出现"环",就像下图这样 ...

  8. 【IT笔试面试题整理】判断链表是否存在环路,并找出回路起点

    [试题描述]定义一个函数,输入一个链表,判断链表是否存在环路,并找出回路起点 Circular linked list: A (corrupt) linked list in which a node ...

  9. 牛客题霸 判断链表中是否有环 C++题解/答案

    牛客题霸 判断链表中是否有环 C++题解/答案 题目描述 判断给定的链表中是否有环 扩展: 你能给出空间复杂度的解法么? 题解: 在这介绍一个简便的方法:快慢指针 就是:一个指针走两步,一个指针走一步 ...

最新文章

  1. 人脸识别中的人脸监测、定位校准和对比等技术
  2. 网易会议开源指南 | 极速构建你的专属会议软件!
  3. 【BZOJ2073】[POI2004]PRZ 状压DP
  4. extjs展示列表,显示来很多空白行,但是数据没显示
  5. jQuery formValidator表单验证插件4.1.1提供下载
  6. Git upstream
  7. 分段函数是不是一定初等函数_分段函数的微积分例题选讲
  8. Oracle Study之案例--安装Oracle内核参数配置
  9. linux 下压缩解压命令
  10. 微机原理 寻址方式 及基于EMU8086的用例
  11. 易语言夜神模拟器操控模块调用方法
  12. git pull 提示当前不在某个分支上解决办法
  13. 国内有哪些不错的CV(计算机视觉)团队?
  14. 求最大公约数的4种常用算法
  15. vue的事件修饰符之.prevent
  16. 计算机会说,计算机会有意识吗?你以为就我们才有吗~
  17. android 闪屏动态界面,Android开发 关于避免切换主题时闪屏的几种方式
  18. 天猫商城在线购物系统
  19. NPOI写Excel,Microsoft.Office.Interop.excel.dll 转换Excel为PDF
  20. 宝塔Linux面板的安装配置以及基本使用教程(超详细)

热门文章

  1. 机器学习(决策树一)——最直白的话来说信息熵
  2. 圆方树学习记录及例题
  3. python对于前端开发有用吗_python和前端开发怎么抉择?
  4. 图书管理系统面向对象分析与设计报告
  5. 数据库设计基本步骤 / 数据库设计原则
  6. Table中collapseColumns,stretchColumns
  7. 成功项目的经验(转载)
  8. 论文解读 - 城市自动驾驶车辆运动规划与控制技术综述 (第2部分)
  9. C#2022/11/2
  10. 安卓版Chrome 已有暗黑模式了!这篇教你怎么开启暗黑模式