1. 环形链表检测问题概述
遇到链表相关算法题时,环形链表检测是个经典问题。142题要求不仅判断链表是否有环,还要找出环的入口节点。这个问题在技术面试中出现频率极高,我曾在多次大厂面试中遇到不同变种。
实际开发中,环形链表检测算法常用于内存管理、资源依赖分析等场景。比如检测内存泄漏时,如果对象引用形成了环,就会导致无法被垃圾回收。掌握这个算法不仅能通过面试,对理解计算机底层机制也很有帮助。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题分析与解题思路
2.1 问题描述
给定一个链表,需要:
- 判断是否存在环
- 如果存在环,返回环的入口节点
- 如果不存在环,返回null
示例:
输入:head = [3,2,0,-4], pos = 1(-4节点指向2节点)
输出:返回索引为1的节点
2.2 关键难点解析
这个问题有两个关键点:
- 如何高效判断链表有环(避免使用O(n)空间)
- 如何准确定位环的入口节点
常规思路是用HashSet记录访问过的节点,空间复杂度O(n)。但面试官通常期望更优解。
3. 最优解法:快慢指针法
3.1 算法原理
快慢指针法(Floyd判圈算法)是解决这类问题的黄金标准:
- 慢指针每次移动1步
- 快指针每次移动2步
- 如果两指针相遇,说明有环
- 相遇后,将其中一个指针移回起点,两指针同速移动,再次相遇点即为环入口
数学证明:
设头节点到环入口距离为a,环入口到相遇点距离为b,相遇点到环入口距离为c
当两指针相遇时:
慢指针走了a+b
快指针走了a+n(b+c)+b
由于快指针速度是慢指针2倍:
2(a+b) = a+n(b+c)+b
化简得:a = (n-1)(b+c)+c
这意味着,从起点到环入口的距离a,等于从相遇点走c加上n-1圈环长。
3.2 代码实现(Python)
python复制def detectCycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast: # 相遇点
slow = head #
