Java算法(01) -- 如何判断链表有环

本文详细解析了三种判断单向链表是否存在环的方法:逐一比对、HashSet存储和双指针法,重点介绍了双指针法的原理和代码实现,帮助理解链表算法和优化时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、题目分析

有一个单向链表,链表中有可能出现“环”,就像下图这样。如何用程序来判断该链表是否为有环链表呢?
在这里插入图片描述

方法一

方法流程:

  • 从头节点开始,依次遍历单链表中的每一个节点;
  • 每遍历一个新节点,就从头检查新节点之前的所有节点,用新节点和此节点之前所有节点依次做比较;
  • 如果发现新节点和之前的某个节点相同,则说明该节点被遍历过两次,链表有环;
  • 如果之前的所有节点中不存在与新节点相同的节点,就继续遍历下一个新节点,继续重复上述的操作

具体流程:
在这里插入图片描述

  • 如上图,当遍历链表节点7时,从头访问节点5和节点3,发现已遍历的节点中并不存在节点7,则继续往下遍历;
  • 当第2次遍历到节点2时,从头访问曾经遍历过的节点,发现已经遍历过节点2, 说明链表有环;

假设链表的节点数量为n,则该解法的时间复杂度为O(n²);由于并没有创建额外的存储空间,所以空间复杂度为O(1)

方法二

方法流程:

  • 创建一个以节点ID为Key的HashSet集合,用来存储曾经遍历过的节点;
  • 从头节点开始,依次遍历单链表中的每一个节点,每遍历一个新节点,都用新节点和HashSet集合中存储的节点进行比较;
  • 如果发现HashSet中存在与之相同的节点ID,则说明链表有环;
  • 如果HashSet中不存在与新节点相同的节点ID,就把这个新节点ID存入HashSet中,之后进入下一节点,继续重复刚才的操作

具体流程:

  • 遍历过5、3,如下图:
    在这里插入图片描述
  • 遍历过5、3、7、2、6、8、1,如下图:
    在这里插入图片描述
  • 当再一次遍历节点2时,查找HashSet,发现节点已存在
    在这里插入图片描述
    由此可知,链表有环;这个方法在流程上和方法1类似,本质的区别是使用了HashSet作为额外的缓存
    【假设链表的节点数量为n,则该解法的时间复杂度是O(n);由于使用了额外的存储空间,所以算法的空间复杂度同样是O(n)】

方法三【双指针】

方法流程:

  • 创建两个指针p1和p2(在Java里就是两个对象引用),让它们同时指向这 个链表的头节点;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值