返回
揭秘环路背后的秘密:利用快慢指针破解LeetCode面试题 02.08
前端
2023-09-17 22:26:55
在 LeetCode 上,面试题 02.08 抛出了一个环路检测难题。它要求你给定一个链表,找出环路的开头节点,如果不存在环路,则返回 null
。这道题目看似简单,却蕴藏着破解环路背后的奥秘。
环路检测之法:快慢指针
应对环路检测,我们引入了快慢指针的巧妙技巧。首先,我们将两个指针 slow
和 fast
都指向链表的头节点。slow
每次前进一步,fast
每次前进两步。如果链表中有环路,fast
最终会追上 slow
。
此刻,我们暂停 fast
,并让 slow
继续前进。每一步,slow
都沿着环路向后移动,fast
则停留在环路上。当 slow
再次遇到 fast
时,我们就可以确定环路的起点。
算法详解
- 初始化: 将
slow
和fast
指针都指向链表的头节点。 - 快慢指针:
fast
每一次前进两步,而slow
每一次前进一步。- 如果存在环路,
fast
最终将追上slow
。
- 确定环路起点:
- 一旦
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 环路检测问题,关键在于快慢指针的妙用。通过让指针以不同的速度前进,我们能够检测环路并确定其起点。这种技巧在解决其他环路相关问题中也大有裨益,彰显了计算机科学中算法的巧妙与优雅。