LeetCode Hot100(22/100)——141. 环形链表

文章目录

一、题目简介

给定一个单链表的头结点 head,判断这个链表中是否存在环。如果链表中存在某个节点,通过不断地 next 指针可以再次到达该节点,就说明链表中存在环。

👉 返回结果:

  • 存在环 ⇒ true
  • 无环 ⇒ false

二、问题抽象化与示意图

我们可以把链表抽象成一个节点序列,每个节点指向下一个节点。如果在某处某个节点的 next 指针指向了前面的节点,就形成了"环"。

下面用一个简化的示意来展示这种结构:
Head
Node 2
Node 3
Node 4

🔁 可以看到:节点 D 的指针指向了节点 B,使得链表循环回去形成了环。


三、解法一:哈希表法(检测重复节点)

原理说明

  • 用一个哈希表(如 HashSet)记录访问过的节点。
  • 每访问一个节点,就检查它是否已经存在于哈希表中。
  • 如果存在,则说明链表中出现了环。
  • 若遍历到 null 说明到达链表尾部,没有环。

解法流程图

Yes
Yes
No
No
Start
Set current = head
current != null ?
current in visitedSet ?
Return true
Add current to visitedSet
Move current to current.next
Return false

时间与空间复杂度

  • 时间复杂度:O(n)(每个节点最多访问一次)
  • 空间复杂度:O(n)(哈希表存储节点引用)

Java 代码实现

java 复制代码
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> visited = new HashSet<>();
        ListNode current = head;
        while (current != null) {
            if (visited.contains(current)) {
                return true;
            }
            visited.add(current);
            current = current.next;
        }
        return false;
    }
}

四、解法二:快慢指针法(Floyd 判圈算法)

原理说明

又称为"龟兔赛跑算法"(Tortoise and Hare Algorithm):

  • 设置两个指针:慢指针 slow 每次走一步;快指针 fast 每次走两步。
  • 如果链表没有环,fast 会先到达末尾(null)。
  • 如果链表有环,slowfast 最终会在环内某处相遇。

时序示意图

节点序列 fast指针 slow指针 节点序列 fast指针 slow指针 初始化:slow = head, fast = head 否则继续移动,直到 fast == null 或相遇 fast前进两步 slow前进一步 如果两者指向同一节点 ⇒ 存在环

解法流程图

Yes
Yes
No
No
Start
slow = head, fast = head
fast != null && fast.next != null ?
slow = slow.next
fast = fast.next.next
slow == fast ?
Return true
Return false

时间与空间复杂度

  • 时间复杂度:O(n)(快慢指针在环中最多相遇一次)
  • 空间复杂度:O(1)(只使用常数额外空间)

Java 代码实现

java 复制代码
public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) return false;

        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return true; // 二者相遇,存在环
            }
        }
        return false; // fast 到达末尾,无环
    }
}

五、总结

方法 原理 时间复杂度 空间复杂度 适用场景
哈希表法 使用集合检测重复节点 O(n) O(n) 简单易懂但消耗额外空间
快慢指针法 双指针运动相遇判环 O(n) O(1) 更高效,推荐使用
相关推荐
2301_790300962 小时前
C++与Docker集成开发
开发语言·c++·算法
一起养小猫2 小时前
Flutter for OpenHarmony 进阶:递归算法与数学证明深度解析
算法·flutter
赛博云推-Twitter热门霸屏工具2 小时前
Twitter 搜索霸屏的关键词工程方法——从算法理解到赛博云推的系统化执行
算法·twitter·dreamweaver
罗湖老棍子2 小时前
【区间DP】括号序列:如何求解最长合法子序列?(POJ 2955)
算法·动态规划·区间dp·区间动态规划·端点匹配型
王德博客2 小时前
【实现常见排序算法】直接插入排序的算法思想
数据结构·算法·排序算法
m0_564876842 小时前
分布式训练DP与DDP
人工智能·深度学习·算法
纤纡.2 小时前
逻辑回归实战进阶:交叉验证与采样技术破解数据痛点(一)
算法·机器学习·逻辑回归
重生之后端学习2 小时前
146. LRU 缓存
java·数据结构·算法·leetcode·职场和发展
程曦曦2 小时前
原地删除有序数组重复项:双指针法的艺术与实现
数据结构·算法·leetcode