本文最后更新于132 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
🔗 环形链表
📌 题目描述
给你一个链表的头节点 head,判断链表中是否有环。
- 环的定义:链表中某个节点的
next指针指向了链表中之前的某个节点,从而形成一个闭环。 - 如果存在环,返回
true;否则,返回false。
✅ 示例解析
示例 1:

- 输入:
head = [3,2,0,-4],pos = 1 - 输出:
true - 解释:链表尾部(
-4)连接到索引为1的节点(即2),形成环。
示例 2:

- 输入:
head = [1,2],pos = 0 - 输出:
true - 解释:尾部(
2)连接到头节点(1),形成环。
示例 3:

- 输入:
head = [1],pos = -1 - 输出:
false - 解释:只有一个节点,且无环。
⚠️ 提示
- 链表中节点的数目范围是
[0, 10⁴] -10⁵ <= Node.val <= 10⁵pos为-1或链表中的一个有效索引
💡 解法:快慢指针(Floyd 判圈算法)—— O(n) 时间,O(1) 空间
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next; // 快指针每次走两步
slow = slow.next; // 慢指针每次走一步
if (fast == slow) { // 快慢指针相遇,说明有环
return true;
}
}
return false; // 快指针到达末尾,无环
}
}
📊 复杂度分析
- 时间复杂度:O(n)
- 如果无环:
fast指针最多走n/2步到达末尾。 - 如果有环:
fast和slow指针在环内最多经过O(环的长度)步后相遇。 - 总体为线性时间。
- 如果无环:
- 空间复杂度:O(1) ✅
- 仅使用两个指针
fast和slow,无需额外存储。
- 仅使用两个指针
🧩 解题思路
- 核心思想:快慢指针相遇则有环
- 使用两个指针:
slow:每次移动 1 步。fast:每次移动 2 步。
- 如果链表无环,
fast指针会先到达末尾(null)。 - 如果链表有环,
fast和slow指针最终会在环内相遇(因为fast在追赶slow)。
- 使用两个指针:
- 为什么快慢指针一定能相遇?
- 设环的长度为
C,slow进入环时,fast已经在环内某处。 - 此时
fast和slow之间的距离为d。 - 由于
fast每次比slow多走 1 步,它们之间的距离每轮减少 1。 - 经过
d轮后,fast会追上slow,即两者相遇。 - 因此,只要存在环,快慢指针必然相遇。
- 设环的长度为
- 代码逻辑详解:java深色版本
while (fast != null && fast.next != null)- 循环条件:确保
fast.next.next不会空指针异常。 - 如果
fast == null或fast.next == null,说明已到链表末尾,无环。
fast = fast.next.next; slow = slow.next;- 快指针走两步,慢指针走一步。
if (fast == slow) return true;- 相遇即返回
true。
- 循环条件:确保
- 举例说明: 对
head = [3,2,0,-4],环连接到索引1(即2):- 初始:
fast = 3,slow = 3 - 第1轮:
fast = 0,slow = 2 - 第2轮:
fast = -4,slow = 0 - 第3轮:
fast = 0,slow = -4 - 第4轮:
fast = -4,slow = 2 - 第5轮:
fast = 2,slow = 0 - 第6轮:
fast = 0,slow = -4 - 第7轮:
fast = 2,slow = 2→ 相遇! → 返回true✅
- 初始:
- 边界处理:
- 空链表:
head == null→fast == null→ 循环不执行 → 返回false。 - 单节点无环:
fast.next == null→ 循环不执行 → 返回false。 - 单节点有环:
head.next = head→fast = head.next.next = head,slow = head.next = head→fast == slow→ 返回true。
- 空链表:
✨ 为什么叫 Floyd 判圈算法?
该算法由计算机科学家 Robert W. Floyd 提出,也称为“龟兔赛跑”算法(Tortoise and Hare Algorithm)。
- 慢指针像“乌龟”,每次走一步。
- 快指针像“兔子”,每次走两步。
- 如果赛道是环形的,兔子终会追上乌龟。

