方法一:首先从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就从头节点重新遍历新节点之前的所有节点,用新节点ID和此节点之前所有节点ID依次作比较。*如果发现新节点之前的所有节点当中存在相同节点ID,则说明该节点被遍历过两次,链表有环*;如果之前的所有节点当中不存在相同的节点,就继续遍历下一个新节点,继续重复刚才的操作。

例如这样的链表:A->B->C->D->B->C->D, 当遍历到节点D的时候,我们需要比较的是之前的节点A、B、C,不存在相同节点。这时候要遍历的下一个新节点是B,B之前的节点A、B、C、D中恰好也存在B,因此B出现了两次,判断出链表有环。

假设从链表头节点到入环点的距离是D,链表的环长是S。那么算法的时间复杂度是0+1+2+3+….+(D+S-1) = (D+S-1)*(D+S)/2 , 可以简单地理解成 O(N*N)。而此算法没有创建额外存储空间,空间复杂度可以简单地理解成为O(1)

方法二:首先创建一个以节点ID为键的HashSet集合,用来存储曾经遍历过的节点。然后同样是从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就用新节点和HashSet集合当中存储的节点作比较,如果发现HashSet当中存在相同节点ID,则说明链表有环,如果HashSet当中不存在相同的节点ID,就把这个新节点ID存入HashSet,之后进入下一节点,继续重复刚才的操作。

这个方法在流程上和方法一类似,本质的区别是使用了HashSet作为额外的缓存

假设从链表头节点到入环点的距离是D,链表的环长是S。而每一次HashSet查找元素的时间复杂度是O(1), 所以总体的时间复杂度是1*(D+S)=D+S,可以简单理解为O(N)。而算法的空间复杂度还是D+S-1,可以简单地理解成O(N)

最终版本:

方法三:(快慢指针法)
首先创建两个指针1和2(在java里就是两个对象引用),同时指向这个链表的头节点。然后开始一个大循环,在循环体中,让指针1每次向下移动一个节点,让指针2每次向下移动两个节点,然后比较两个指针指向的节点是否相同。如果相同,则判断出链表有环,如果不同,则继续下一次循环。

例如链表A->B->C->D->B->C->D,两个指针最初都指向节点A,进入第一轮循环,指针1移动到了节点B,指针2移动到了C。第二轮循环,指针1移动到了节点C,指针2移动到了节点B。第三轮循环,指针1移动到了节点D,指针2移动到了节点D,此时两指针指向同一节点,判断出链表有环。

此方法也可以用一个更生动的例子来形容:在一个环形跑道上,两个运动员在同一地点起跑,一个运动员速度快,一个运动员速度慢。当两人跑了一段时间,速度快的运动员必然会从速度慢的运动员身后再次追上并超过,原因很简单,因为跑道是环形的。

假设从链表头节点到入环点的距离是D,链表的环长是S。那么循环会进行S次(为什么是S次,有心的同学可以自己揣摩下),可以简单理解为O(N)。除了两个指针以外,没有使用任何额外存储空间,所以空间复杂度是O(1)。

LinkedListNode detect(LinkedListNode head) {LinkedListNode runner = head;LinkedListNode walker = head;while (runner != null && runner.next != null) {runner = runner.next.next;walker = walker.next;if (runner == walker) break;}if (runner == null || runner.next == null) return null;walker = head;while (runner != walker) {runner = runner.next;walker = walker.next;}return runner;
}

数据结构面试 之 单链表是否有环及环入口点 附有最详细明了的图解
http://www.jianshu.com/p/ef71e04241e4

java工程师面试题:如何判断链表有环?相关推荐

  1. 2021年超全中高级Java工程师面试题+答案

    今天博主为大家汇总了史上最全的中高级JAVA工程师面试题及答案,分别是java缓存技术面试题和java中的hashmap面试题,希望能够帮助到正在找工作的中高级JAVA程序员,下面就随博主一起来看看吧 ...

  2. java工程师考试题目_成功拿到Offer,Java工程师笔试题及答案!

    1.是否可以从一个static方法内部发出对非static方法的调用? 不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时 ...

  3. 北京南天软件java工程师面试题

    此试题为北京南天软件java工程师面试题(部分) 一.单项选择 (1)下列关于构造方法的叙述中,错误的是(C) A.java语言规定构造方法名与类名必须相同 B.java语言规定构造方法没有返回值,但 ...

  4. java面试题_1000道Java工程师面试题+答案PDF485页

    说实话,作为一名 Java 程序员,不论你需不需要面试都应该好好看下这份资料.我大概撸了一遍,真的是堪称典范. 就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常 ...

  5. 深圳Java学习:分享几道真实的企业Java工程师笔试题

    深圳Java学习:分享几道真实的企业Java工程师笔试题,你都会做吗?

  6. Java工程师笔试题整理[校招篇]

    Java工程师笔试题整理[校招篇] 阿里巴巴 2016 阿里巴巴2016研发工程师笔试题(四) 阿里巴巴2016研发工程师笔试题(三) 阿里巴巴2016研发工程师笔试题(二) 2015 阿里巴巴201 ...

  7. 2022 最新 互联网 Java 工程师面试题

    互联网 Java 工程师面试题 内容涵盖:Java.MyBatis.ZooKeeper.Dubbo.Elasticsearch.Memcached. Redis.MySQL.Spring.Spring ...

  8. 2022年最新Java工程师面试题从基础到中级到高级

    2022年最新Java工程师面试题从基础到中级到高级 一.基础 Java面向对象有哪些特征,如何应用 面向对象编程是利用类和对象编程的一种思想.万物可归类,类是对于世界事物的高度抽象 ,不同的事物之间 ...

  9. 2020 Java工程师面试题汇总

    前言 2020,不平凡的一年. 经过一个多月的面试,整理了一些面试题,分享出来.不敢说对大家能有多大帮助,至少可以查漏补缺吧. 里面很多东西,写得很长,并不是说要死记硬背,而是要理解,一次不懂,多看几 ...

  10. Java工程师面试题之Spring Cloud(含答案)

    学习目标: 1.一周掌握 JAVA入门知识 2.掌握基础入门C#知识 3.手把手教你vbs脚本制作 4.强大的 IDEA编程利器 5.经典常见的 面试题目技巧 Java工程师面试题之Spring Cl ...

最新文章

  1. 抽象类的基本概念------abstract
  2. python输入输出-2. Python中的基本输入、输出、格式化输出
  3. 添加第三方类库造成的linker command failed with exit code 1 (use -v to see invocation)的错误调试
  4. Index of school
  5. 初识jQuery(适合初学者哟.........)
  6. 006 list类型
  7. 微信小程序之旅一(注册页面的使用)
  8. 双纵坐标的绘图命令_Matplotlib绘图 | 快速定义图表样式的小技巧
  9. python之HTML文件转PDF文件,python之把HTML文件转换成PDF格式文档
  10. 软件工程4 用例建模
  11. xp系统的计算机设置在哪里,请问在XP系统中怎样设置输入法
  12. 50 行代码,实现中英文翻译
  13. 机器学习(周志华) 第五章神经网络
  14. 一起avi文件播放时没有图像问题的解决(tscc.exe)
  15. 获取CPU型号和序列号
  16. 也谈地方门户网站运营
  17. ICMP报文格式解析
  18. PHP天天竞拍手机网站源码,天天试用源码竞拍源码
  19. MSN登陆不上去的解决方法
  20. 突发事件应急通信保障系统解决方案

热门文章

  1. spark任务提交流程源码分析
  2. 设计模式之不简单的工厂模式(三)
  3. 动态规划入门(一)——数字三角形
  4. Java访问修饰符——用于控制可见性
  5. nio的优势_BIO、NIO、AIO 介绍和适用场景分析
  6. axios 使用步骤很简单,首先在前端项目中,引入 axios:
  7. 第十三篇:multimap容器和multiset容器中的find操作
  8. 冲刺!11.14-11.15
  9. dotnetnuke|dnn 内网实现自动登录
  10. DSS流媒体服务器搭建