1、题目描述
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
-
链表中节点的数目范围是
[0, 104]
-
-105 <= Node.val <= 105
-
pos
为-1
或者链表中的一个 有效索引 。
进阶:你能用 O(1)
(即,常量)内存解决此问题吗?
2、方法1:哈希
解题思路
-
初始化哈希集合:创建一个
HashSet
来存储已经访问过的节点引用(地址)。 -
遍历链表:
-
从链表头节点
head
开始,依次访问每个节点。 -
对于当前节点
head
:-
如果
head
已经存在于HashSet
中:-
说明该节点之前已经被访问过,链表存在环,直接返回
true
。
-
-
如果
head
不在HashSet
中:-
将该节点加入
HashSet
,表示已经访问过。 -
移动
head
指针到下一个节点(head = head.next
)。
-
-
-
-
遍历结束:
-
如果
head
移动到null
,说明链表无环,返回false
。
-
关键点:
-
哈希集合存储的是节点引用(地址),而不是节点的值(
val
),因此可以正确处理链表中有重复值的情况。 -
时间复杂度:O(n),需要遍历整个链表。
-
空间复杂度:O(n),最坏情况下需要存储所有节点。
代码
//使用哈希set来解题
public static boolean isCycle(ListNode head){
if (head == null) return false;
HashSet<ListNode> visited = new HashSet<>();
while (head != null){
if (visited.contains(head)) { //存在,说明已经访问过该节点,说明有环
return true;
}
//无环,将该节点存放到hashset中,并指针下移
visited.add(head);
head = head.next;
}
return false; //最后因为循环到null,说明无环,返回false
}
3、方法2:快慢指针
解题思路
-
初始化指针:
-
慢指针
l
指向头节点head
。 -
快指针
r
指向head.next
(初始时快指针比慢指针快一步)。
-
-
遍历链表:
-
循环条件:
l != r
(即快慢指针未相遇)。 -
在循环中:
-
检查快指针是否能移动两步:
-
如果
l.next
和r.next
均不为null
,则:-
慢指针
l
移动一步(l = l.next
)。 -
快指针
r
移动两步(r = r.next.next
)。
-
-
-
如果快指针无法移动两步:
-
说明链表无环(因为快指针已经到达链表末尾),直接返回
false
。
-
-
-
-
循环结束:
-
如果退出循环,说明
l == r
,即快慢指针相遇,链表存在环,返回true
。
-
关键点
-
快慢指针的速度差:
-
慢指针每次移动一步,快指针每次移动两步。
-
如果有环,快指针最终会追上慢指针(类似于跑步套圈)。
-
-
无环的判断:
-
如果快指针遇到
null
,说明链表无环。
-
-
时间复杂度:O(n),快指针遍历速度更快。
-
空间复杂度:O(1),仅需两个指针,无需额外空间。
代码
//使用快慢指针解题
public static boolean isCycle1(ListNode head){
if (head == null) return false;
ListNode last = head, fast = head;
while (fast != null && fast.next != null && fast.next.next != null){
last = last.next;
fast = fast.next.next;
if (fast == last) return true;//当相遇说明有环
}
return false;//当退出循环,说明无环
}