142_环形链表 II[MEDIUM]
约 408 字大约 1 分钟
2026-03-21
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
不允许修改链表。
示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。解题思路
解法1:哈希表
遍历链表,同时把节点存到 HashSet 中,循环时判断节点是否已经在 HashSet 存在过,如果是,直接返回该节点,否则一直循环到链表末尾(node.next == null)说明无环
解法2:快慢指针
有以下定理:从头节点出发到环入口的距离(a),等于从相遇点继续走回到入口的距离
2 -> 5 -> 0 -> 1 -> 3 -> 7 -> 6 -> 8
^ |
|———————————————————|
假如相遇点为 7 ,那么:
2 -> 5 -> 0 -> 1 的距离是 4
7 -> 6 -> 8 -> 1 的距离也是 4先用快慢指针判断链表有环,然后把 slow 指针调到 head, 两边同步走,再次相遇时,就是入环节点
Java 实现
快慢指针
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
// 第一阶段:寻找相遇点
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// 发现环
if (slow == fast) {
// 第二阶段:寻找入口
ListNode index1 = head;
ListNode index2 = slow;
while (index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
return index1; // 返回入口节点
}
}
return null; // 无环
}