问题:如何判断一个单向链表中是否存在环?

例如:

链表中存在环(B-->D):<-- <--^|       |v       |
A-->B-->C-->D链表中不存在环:A-->B-->C-->D-->E-->F

解题思路:

  从一个实际的生活场景出发,两个人,在一个环形的操场上跑步的时候,如果有一个人跑得比另一个人还要快,那么,在n圈之后,这两个人总会在操场上的某个点相遇。将操场类比于链表中存在的环路径,将两个人看成两个指针,那么这道题的解题思路就自然而然的出来了。

具体步骤如下:

  1. 初始化两个指针a,b,同时指向链表的开头
  2. a指针走一步,b指针走两步(我们姑且将a指针称为慢指针,将b指针称为快指针)
  3. 重复步骤2,直到b指针无法继续往下走两步或者a,b指针相遇
  4. 当b指针无法继续往下走两步的时候,说明链表中不存在环,b指针即将走到链表的末尾端。
  5. 当a,b指针相遇,说明链表中存在环,因为只有存在环的情况,a,b指针才有可能会在环中的某个点相遇

具体代码如下:

/*** @author 学徒** 用于判断链表中是否存在环**/
public class CycleLinkedList {/*** 循环链表中的节点类*/static class Node<T>{//节点值T value;//节点的下一个节点的指针Node<T> next;public Node(T value){this(value,null);}public Node(T value,Node next){this.next=next;this.value=value;}}/*** 用于判断该链表中是否存在着环* @param head 链表的头节点* 当存在环时,返回true,否则返回false*/public boolean judge(Node head) {if(head==null){return false;}//两个指向头结点的指针Node a=head,b=head;while(true){if(b.next==null||b.next.next==null){return false;}a=a.next;b=b.next.next;if(a==b){return true;}}}public static void main(String[] args){Node<String> a=new Node<String>("A");Node<String> b=new Node<String>("B");Node<String> c=new Node<String>("C");Node<String> d=new Node<String>("D");a.next=b;b.next=c;c.next=d;d.next=b;CycleLinkedList list=new CycleLinkedList();boolean result=list.judge(a);System.out.println("链表中环的结果:"+result);}
}

  从上面的链表中是否存在环的问题,可以延伸出与链表中是否存在环相关的另一个问题

问题: 链表中构成环的元素的个数应该如何计算?

  对于这个问题,我们稍微沿着解决上面的链表存在环的问题的思路继续往下想,当链表中存在环的时候,快慢指针相遇,那么这个时候,我们只需要让快指针停留在相遇的位置,让慢指针再次走一遍,边走边记录步数,当快慢指针再次相遇的时候,慢指针所走的步数,便是构成环的链表的环中元素个数。

我们只需要稍微修改下上面的代码即可,具体代码如下:

/*** @author 学徒** 用于判断链表中是否存在环**/
public class CycleLinkedList {/*** 循环链表中的节点类*/static class Node<T>{//节点值T value;//节点的下一个节点的指针Node<T> next;public Node(T value){this(value,null);}public Node(T value,Node next){this.next=next;this.value=value;}}/*** 用于判断该链表中是否存在着环* @param head 链表的头节点* 当存在环时,返回环中元素个数,否则返回0*/public int judge(Node head) {if(head==null) {return 0;}//两个指向头结点的指针Node a=head,b=head;while(true){//当出现该情况的时候,说明无环if(b.next==null||b.next.next==null){return 0;}a=a.next;b=b.next.next;//当其存在环if(a==b){int number=1;a=a.next;while(a!=b){a=a.next;number++;}return number;}}}public static void main(String[] args){Node<String> a=new Node<String>("A");Node<String> b=new Node<String>("B");Node<String> c=new Node<String>("C");Node<String> d=new Node<String>("D");a.next=b;b.next=c;c.next=d;d.next=b;CycleLinkedList list=new CycleLinkedList();int result=list.judge(a);System.out.println(result);}
}

  顺着上面的问题继续的往下想,我们可以延伸出另一个问题

问题:我们是否可以得到第一个进入该链表的环的节点的元素?

  对于该问题,我们可以通过以下的方式得到该节点。

  1. 将快指针重新指向链表的头节点
  2. 快指针和慢指针同时走,当快指针和慢指针相遇时,该节点便是链表中第一个进入环的节点

ps:以上只是一个结论的步骤总结。实际上,可以通过分析得到,在环中,快慢指针第一次相遇时的节点位置与进入环的第一个节点的顺时针方向的距离同链表头节点到进入环中第一个节点的位置的距离相等。

具体代码如下:

/*** @author 学徒** 用于判断链表中是否存在环**/
public class CycleLinkedList {/*** 循环链表中的节点类*/static class Node<T>{//节点值T value;//节点的下一个节点的指针Node<T> next;public Node(T value){this(value,null);}public Node(T value,Node next){this.next=next;this.value=value;}}/*** 用于判断该链表中是否存在着环* @param head 链表的头节点* 当存在环时,返回环中元素个数,否则返回0*/public Node judge(Node head) {if(head==null) {return null;}//两个指向头结点的指针Node a=head,b=head;while(true){//当出现该情况的时候,说明无环if(b.next==null||b.next.next==null){return null;}a=a.next;b=b.next.next;//当其存在环if(a==b){b=head;while(a!=b){a=a.next;b=b.next;}return b;}}}public static void main(String[] args){Node<String> a=new Node<String>("A");Node<String> b=new Node<String>("B");Node<String> c=new Node<String>("C");Node<String> d=new Node<String>("D");a.next=b;b.next=c;c.next=d;d.next=b;CycleLinkedList list=new CycleLinkedList();Node result=list.judge(a);System.out.println(result.value);}
}

主目录:

回到目录|·(工)·)

转载于:https://www.cnblogs.com/MyStringIsNotNull/p/9125252.html

Q:判断链表中是否存在环的相关问题相关推荐

  1. 【Java】环形链表 ( 给定一个链表,判断链表中是否有环)

    题目描述 :给你一个链表的头节点 head ,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,评测系统内部使用整数 po ...

  2. 判断链表中是否有环(环形链表)

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

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

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

  4. 1:算法php/go [反转链表;LRU缓存结构 ;判断链表中是否有环]

    目录 2021-12-01反转链表 12/10 设计LRU缓存结构 (参考牛客网) 判断链表中是否有环(参考牛客网) 给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头. 数据 ...

  5. 环形链表。给定一个链表,判断链表中是否有环。(GO、PHP)

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

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

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

  7. 给定一个链表,判断链表中是否有环

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

  8. 数据结构初阶(4)(OJ练习【判断链表中是否有环、返回链表入口点、删除链表中的所有重复出现的元素】、双向链表LinkedList【注意事项、构造方法、常用方法、模拟实现、遍历方法、顺序表和链表的区别)

    接上次博客:数据结构初阶(3)(链表:链表的基本概念.链表的类型.单向不带头非循环链表的实现.链表的相关OJ练习.链表的优缺点 )_di-Dora的博客-CSDN博客 目录 OJ练习 双向链表--Li ...

  9. 链表系列--判断链表中是否有环。

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

  10. 详解:如何判断链表中是否有环?

    如何判断链表中是否有环是一道非常经典的题目,下面用3种方法实现. 方法一:暴力双重循环 直接使用双重循环,没什么好讲的. 方法二:使用HashSet 在方法一的基础上进行优化降低复杂度,使用hashS ...

最新文章

  1. Android爬坑之旅:软键盘挡住输入框问题的终极解决方式
  2. Linux 爱好者的飞行棋:sudo
  3. ListView中的图片异步加载、缓存
  4. AnalyticDB - 分析型数据库
  5. 【Android Developers Training】 58. 缓存位图
  6. intl扩展 mac 安装php_mac下php安装intl扩展代码分享
  7. eNSP模拟器拓扑图:浮动路由的实际作用和分析,默认路由的配置,抓包分析
  8. [译]应用内搜索功能实现 Android TV应用程序手册教程十三
  9. 电脑网络里显示有两台计算机,2台电脑能共用一个显示器吗
  10. C#窗体标准计算器(上) 初级新手请多担待。
  11. 图像处理4:最大类间方差法(大津法)
  12. 医院信息化建设,该何去何从?
  13. 斗地主发牌游戏编程java,自己做的斗地主游戏发牌C#程序
  14. 密码库LibTomCrypt学习记录——(2.13)分组密码算法的工作模式——CCM加密认证模式
  15. excel随机数_【收藏】Excel生成随机数、不重复随机数技巧,试验检测办公必备...
  16. UFS学习一:UTP层和UPIU
  17. MD5简介与代码实现
  18. 脱壳-ASPack 2.12
  19. nmap工具进行端口扫描
  20. 半监督学习matlab,基于自适应图的半监督学习方法与流程

热门文章

  1. Flink CDC 项目 GitHub star 破 2000,新增 Maintainer 成员
  2. MMP,我兄弟转正前一天,一个垃圾公司把他辞退了!
  3. 10年腾讯技术专家有话对你说
  4. 计算机设备分配资源的发展,分配系统资源
  5. java反射机制的实现机制_Java反射机制实践
  6. wxpython窗口固定大小_调整wxPython窗口的大小
  7. java程序设计中科院_中科院NLPIR中文分词java版
  8. axure element元件_Axure教程,产品小白从0学起
  9. pythonATM,购物车项目实战_补充9文档说明
  10. python-gui-pyqt5的使用方法-4--自定义信号的初识--多参数的使用