返回

揭秘环路背后的秘密:利用快慢指针破解LeetCode面试题 02.08

前端

LeetCode 上,面试题 02.08 抛出了一个环路检测难题。它要求你给定一个链表,找出环路的开头节点,如果不存在环路,则返回 null。这道题目看似简单,却蕴藏着破解环路背后的奥秘。

环路检测之法:快慢指针

应对环路检测,我们引入了快慢指针的巧妙技巧。首先,我们将两个指针 slowfast 都指向链表的头节点。slow 每次前进一步,fast 每次前进两步。如果链表中有环路,fast 最终会追上 slow

此刻,我们暂停 fast,并让 slow 继续前进。每一步,slow 都沿着环路向后移动,fast 则停留在环路上。当 slow 再次遇到 fast 时,我们就可以确定环路的起点。

算法详解

  1. 初始化:slowfast 指针都指向链表的头节点。
  2. 快慢指针:
    • fast 每一次前进两步,而 slow 每一次前进一步。
    • 如果存在环路,fast 最终将追上 slow
  3. 确定环路起点:
    • 一旦 fast 追上 slow,将 fast 暂停并让 slow 继续前进。
    • 每次 slow 前进一步,fast 也前进一步。
    • slow 再次遇到 fast 时,它们位于环路的起点。

实例演示

考虑一个包含环路的链表:1 -> 2 -> 3 -> 4 -> 5 -> 2

步数 slow 位置 fast 位置
1 1 2
2 2 4
3 3 2
4 4 5
5 5 2

在第 5 步,fast 追上了 slow。我们暂停 fast,让 slow 继续前进。

步数 slow 位置 fast 位置
6 1 2
7 2 2

slow 在第 7 步再次遇到了 fast,这表明环路的起点是节点 2。

代码实现

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 head != slow:
                head = head.next
                slow = slow.next
            return head

    return None

总结

破解 LeetCode 02.08 环路检测问题,关键在于快慢指针的妙用。通过让指针以不同的速度前进,我们能够检测环路并确定其起点。这种技巧在解决其他环路相关问题中也大有裨益,彰显了计算机科学中算法的巧妙与优雅。