[LeetCode题解]142. 环形链表 II | 快慢指针
解题思路
本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口。
如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环。那么如何找到入口呢?
如下图所示的链表:
当 fast
与 slow
第一次相遇时,有以下关系:
fast = 2 * slow
slow = a + n*b - c // 假设 slow 走了 n 圈
fast = a + m*b - c // 假设 fast 走了 m 圈
那就有:
a + m*b - c = 2*(a + n*b - c)
继而得到:
a = c + (m-n)*b
而(m-n)*b表示走了 m-n 圈,不影响 c 的大小,即可忽略,最终得到:
a = c
通过上面的推导,我们知道相遇点距环的入口的距离(c)与开头到环的入口的距离(a)相等。
因此当 fast
与 slow
相遇时,只要 fast
重新定位到表头,与 slow
一起走,当它们再次相遇时,就是环的入口。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode DetectCycle(ListNode head) {
ListNode fast = head, slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow) { // 存在环
fast = head;
while(fast != slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
return null;
}
}
复杂度分析
- 时间复杂度:\(O(n)\),其中 \(n\) 是链表长度
- 空间复杂度:\(O(1)\)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用