返回

揭秘LeetCode HOT 100:环形链表 II 中的破解之道

前端

导语

LeetCode HOT 100 挑战是磨炼算法和数据结构技能的绝佳平台。其中,环形链表 II 问题以其中等难度和巧妙的设计而闻名。本文将深入剖析此问题,提供清晰易懂的解决方案,助你攻克这一编程难题。

问题陈述

给定一个链表的头节点 head,判断链表是否存在环。如果存在环,返回环的入口节点;如果不存在环,返回 null

解决思路

要解决环形链表问题,我们需要利用链表的特性。假设链表中存在环,我们可以想象一个乌龟和一只兔子同时从链表头部开始前进。乌龟每次移动一步,兔子每次移动两步。如果存在环,兔子最终将追上乌龟。

基于此思路,我们的算法步骤如下:

  1. 初始化 :设置两个指针 slowfast,均指向链表头部 head
  2. 循环
    • 如果 fastfast.next 为空,则链表中没有环,返回 null
    • 否则,slow 移动一步,fast 移动两步。
  3. 环检测 :如果 slowfast 相遇,则说明链表中存在环。此时,继续让 slow 每次移动一步,直到它也到达环的入口节点。
  4. 入口节点查找slow 遇到环的入口节点后,返回此节点。

代码实现

def detectCycle(head):
    if not head or not head.next:
        return None

    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            while slow != head:
                slow = slow.next
                head = head.next
            return head

    return None

时空复杂度分析

  • 时间复杂度 :O(n),其中 n 为链表长度。这是因为在最坏的情况下,fast 指针必须遍历整个链表才能检测到环。
  • 空间复杂度 :O(1),因为我们只使用两个额外的指针。

总结

通过理解环形链表的特性和乌龟与兔子算法的原理,我们可以高效地解决环形链表 II 问题。这不仅锻炼了我们的算法思维,也为后续解决更复杂的数据结构问题奠定了基础。

拓展阅读