题目描述

判断一个单链表是否有环,有环则返回入环节点,否则返回null

1->2->3->4->5->6↑  ↓8<-7
复制代码

例如上面这个链表就有环,入环节点是5

判断链表有环

通常判断链表是否有环,会采用快慢指针的方法,其实道理很简单,就像两个人赛跑且一个人跑得快一个人跑得慢。如果赛道是直的,那么快人跑到终点时慢人还未到;如果赛道是环形,则快人和慢人总会相遇。
代码实现

    function ListNode(x){this.val = x;this.next = null;}function EntryNodeOfLoop(pHead){if(pHead === null)return null;// 快慢指针从链表的头部开始var fast = pHead;var slow = pHead;while(slow.next !==null && fast.next.next !== null) {// 快指针每次走两步;慢指针每次走一步slow = slow.next;fast = fast.next.next;// 快慢指针相遇时,跳出while循环if(slow === fast)break;}// 快指针已经到了链表尾部了还没和慢指针相遇,说明没有环if(fast === null || fast.next === null)return null;// 后续会处理有环的情况...}
复制代码

找到入环节点

常见的方法是:在确定链表有环之后,慢指针重新指向链表头,快指针留在相遇处;然后快慢指针再以每次移动1个节点的速度前进,最终他们在入环节点相遇。 为什么这么做就可以保证在入环节点相遇?证明一下:

如图,设整个链表长度为L,环长度为R,且距离具有方向性,例如CB是C点到B点的距离,BC是B点到C点的距离,CB!=BC。当证明有环时,fast和slow都顺时针到了B点,则此时:

slow走的距离:AC+CB
fast走的距离:AC+k*R+CB(k=0,1,2...)
复制代码

由于fast每次走2个节点,slow每次走1个节点,所以:

2(AC+CB) = AC+k*R+CB
AC+CB = k*R
AC+CB = (k-1)*R+R
AC = (k-1)*R+R-CB
AC = (k-1)*R+BC
复制代码

从最终的表达式可以看出来,AC的距离等于绕环若干圈后再加上BC的距离,也就是说慢指针从A点出发以速度1前进、快指针从B点出发以速度1前进,则慢指针到C点时,快指针也必然到了。 代码实现:

    function ListNode(x){this.val = x;this.next = null;}function EntryNodeOfLoop(pHead){if(pHead === null)return null;var fast = pHead;var slow = pHead;while(slow.next !==null && fast.next.next !== null) {slow = slow.next;fast = fast.next.next;if(slow === fast)break;}if(fast === null || fast.next === null)return null;// 有环,slow重新回到链表头slow = pHead;// slow和fast重新相遇时,相遇节点就是入环节点while(slow !== fast) {slow = slow.next;fast = fast.next;}return slow;}
复制代码

【刷算法】判断链表是否有环以及返回入环节点相关推荐

  1. LeetCode 141.带环问题(判断是否带环) 142.带环问题(返回入环点)

    目录: 1.带环问题(判断是否带环) (1)题目描述 (2)思路解析 a.问题: 怎么证明快指针和慢指针一定会在环里相遇,而不是一直错过? b.问题:如果slow一次走一步,fast一次走3步?fas ...

  2. C++ 单向链表 —— 初始化、插入、返回第一个节点、删除、查找、长度、打印、反转(逆序)

    单向链表的概念: 如果"一个节点"将指向"另一个节点的指针"作为数据成员,那么多个这样的节点可以连起来,只用一个变量就能够访问整个节点序列,我们称之为链表.如果 ...

  3. (左神)数据结构与算法 ---- 判断链表是否为回文结构的三种高效解法

    链表在数据结构与算法中可谓"北斗之尊",现在让我们通过判断链表回文的小练习进一步更深地了解链表~ 文章目录 一.链表的节点结构 二.判断一个链表是否为回文结构 (一)解法1:将链表 ...

  4. java算法判断链表有没有闭环_前端算法系列之二:数据结构链表、双向链表、闭环链表、有序链表...

    前言 上一次我们讲到了数据结构:栈和队列,并对他们的运用做了一些介绍和案例实践:我们也讲到了怎么简单的实现一个四则运算.怎么去判断标签是否闭合完全等等,anyway,今天接着和大家介绍一些数据结构: ...

  5. 链表:判断链表是否有环以及找入口

    141环形链表 题意: 给定一个链表,判断链表中是否有环.如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连 ...

  6. leetcode刷题笔记-链表的使用

    一.单链表的基础:增删改查 问题:设计一个单链表,要求实现其增删改查功能.707. 设计链表 问题分析 往链表中添加元素的步骤 往链表中删除元素的步骤 注意:对于单链表来说,添加一个无用的头节点,再对 ...

  7. 链表的特点,单链表的定义、存储结构,单链表的基本操作(判断链表是否为空、销毁链表、清空链表、求链表表长、查找、插入、删除,建立单链表)

    目录 一.链表(链式存储结构)的特点 二.单链表的定义和表示 1.带头结点的单链表 2.单链表的存储结构 三.单链表基本操作的实现 1.单链表的初始化(带头结点的单链表) 2.补充单链表的几个常用简单 ...

  8. 算法【链表】 | 【链表尾部重合问题】

    文章目录 一.链表尾部重合 1.步骤 2.代码分块 2.1 数据结构 2.2 获取入环结点 2.3无环链表处理 2.4 有环链表处理 3.代码 一.链表尾部重合 1.步骤 > 首先判断是否有环: ...

  9. 环形链表[快慢指针 入环点]

    环&快慢指针 前言 一.环形链表 二.快慢指针 1.相遇即有环 2.入环点 总结 参考文献 前言 对于环问题,快慢指针是一种常用的手段.一步两步走,通过判定是否相遇来判定是否存在环.而且快慢指 ...

最新文章

  1. 此字符不允许在标识符中使用_计算机中C语言的-基本语法
  2. Ajax应用开发:实践者指南
  3. Android Staido 一直scanning file to index
  4. Groovy初体验:构建高性能JVM应用
  5. 【Oracle 学习笔记】Day 2 视图、序列、同义词
  6. Nearest Opposite Parity(反向建边+spfa)
  7. Winfrom实现圆角设计
  8. oracle如何不让表自动建分区,怎么自动创建表空间和表分区
  9. 洛谷 P1306 斐波那契公约数
  10. register_globals
  11. Java中ArrayList和LinkedList以及queue的模仿
  12. Delphi XE DataSnap三层开发实务
  13. MySQL生成测试数据相关脚本(持续更新)
  14. 一个线程OOM,进程里其他线程还能运行么?
  15. 如何修改PPT文档的编辑版式
  16. 100天带你系统入门VR/AR游戏开发,成为5G时代的“头号玩家”
  17. 和讯金融界证券之星 财经网站竞争格局突变
  18. 【2023年最新版】Kali安装详细教程
  19. 为什么机器人不会抢走你的工作?
  20. 穆迪分析在Chartis报告中被评为CLO解决方案类别领导者

热门文章

  1. 20170608-BOM
  2. Servlet的Filter的使用
  3. phpMyAdmin操作之改管理员密码
  4. Excel报表配置说明
  5. 你最常用的构建和发布管理工具是什么
  6. 今年端午节,想回家看看父母...
  7. 强大的shell常用命令集锦
  8. 使用VS2010编译MongoDB C++驱动详解
  9. Emacs中的RSS阅读器--newsticker
  10. git 基于发布分支的开发