【忍者算法】从入环点到相遇点:深入理解环形链表 II|LeetCode第142题 环形链表 II
【忍者算法】从入环点到相遇点:深入理解环形链表 II|LeetCode第142题
问题升级:不止要找环,还要找入环点
在上一题中,我们讨论了如何判断链表是否有环。现在让我们更进一步:如果确定链表中有环,我们该如何找到环的入口节点?这就像是在环形跑道上不仅要确认跑道是环形的,还要找到环形跑道的起点。
问题描述
LeetCode第142题"环形链表 II"要求:给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 null。
例如:
输入:3 → 2 → 0 → -4
↑___________|
输出:返回节点 2
解释:链表中存在一个环,其尾部连接到第二个节点
从快慢指针相遇谈起
还记得上一题中的快慢指针相遇吗?那个相遇点看似随机,实际上蕴含着重要的数学原理。让我们用这个相遇点来找到入环点。
巧妙的数学关系
假设:
- 链表头到入环点的距离为 a
- 入环点到相遇点的距离为 b
- 相遇点到入环点的距离为 c
当快慢指针相遇时:
- 慢指针走过的距离:a + b
- 快指针走过的距离:a + b + n(b + c),其中n是快指针在环内走的圈数
- 因为快指针速度是慢指针的两倍,所以:2(a + b) = a + b + n(b + c)
通过解这个等式,我们发现:a = c + (n-1)(b + c)
这意味着:从链表头和相遇点同时出发,最终会在入环点相遇!
代码实现
public ListNode detectCycle(ListNode head) {
// 处理特殊情况
if (head == null || head.next == null) {
return null;
}
// 第一阶段:使用快慢指针找到相遇点
ListNode slow = head;
ListNode fast = head;
ListNode intersection = null;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
intersection = slow;
break;
}
}
// 如果没有相遇点,说明无环
if (intersection == null) {
return null;
}
// 第二阶段:从头节点和相遇点同时出发,找入环点
ListNode start = head;
while (start != intersection) {
start = start.next;
intersection = intersection.next;
}
return start;
}
图解过程
1) 初始状态:
3 → 2 → 0 → 4
↑___________|
S,F
2) 快慢指针相遇:
3 → 2 → 0 → 4
↑___________|
S,F
3) 从头和相遇点同时出发:
3 → 2 → 0 → 4
↑___________|
P1 P2
4) 在入环点相遇:
3 → 2 → 0 → 4
↑___________|
P1,P2
与上一题的联系与进阶
相比环形链表I,这一题是一个很自然的进阶:
- 两题都使用了快慢指针技巧
- 这一题复用了上一题找相遇点的过程
- 在找到相遇点后,增加了寻找入环点的步骤
实现细节与优化
- 空间复杂度仍然保持O(1)
- 时间复杂度为O(n)
- 不需要额外的数据结构
- 代码实现优雅且直观
思考与延伸
这个问题告诉我们:
- 有时问题的解决方案就藏在问题本身的特性中
- 数学关系可以帮助我们找到优雅的解法
- 快慢指针不仅能检测环,还能帮我们找到关键节点
实际应用思考
这个算法的思想可以应用在很多实际场景中:
- 检测循环依赖
- 死锁检测
- 循环引用的处理
让我们记住:当我们遇到类似的"寻找特殊点"问题时,可以尝试利用路径特性来找到优雅的解决方案。
作者:忍者算法
公众号:忍者算法
我准备了一份刷题清单,以及这些题目的详细题解,覆盖了绝大部分常见面试题。我可以很负责任地说,只要你把这些题真正掌握了,80%的算法面试都能遇到相似题目。公众号回复【刷题清单】获取~
【忍者算法】从入环点到相遇点:深入理解环形链表 II|LeetCode第142题 环形链表 II的更多相关文章
- 龟兔赛跑算法 floyed判环算法
今天写线段树写到要用到这个算法的题目,简单的学习一下. https://blog.csdn.net/javaisnotgood/article/details/89243876 https://blo ...
- (zhuan) 大牛讲堂 | 算法工程师入门第二期-穆黎森讲增强学习
大牛讲堂 | 算法工程师入门第二期-穆黎森讲增强学习 2017-07-13 HorizonRobotics
- 3,java数据结构和算法:约瑟夫环出队顺序, 单向环形链表的应用
什么是约瑟夫环? 就是数小孩游戏: 直接上代码: 要实现这个,只需要理清思路就好了 孩子节点: class Boy{ int no;//当前孩子的编码 Boy next; // 下一节点 public ...
- 【算法分析】如何理解快慢指针?判断linked list中是否有环、找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked List Cycle II 为例Python实现
引入 快慢指针经常用于链表(linked list)中环(Cycle)相关的问题.LeetCode中对应题目分别是: 141. Linked List Cycle 判断linked list中是否有环 ...
- [LeetCode] 142. Linked List Cycle II 单链表中的环之二
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To r ...
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- LeetCode 上最难的链表算法题,没有之一!
题目来源于 LeetCode 第 23 号问题:合并 K 个排序链表. 该题在 LeetCode 官网上有关于链表的问题中标注为最难的一道题目:难度为 Hard ,通过率在链表 Hard 级别目前最低 ...
- [LeetCode] 141. Linked List Cycle 链表中的环
Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...
- [LeetCode] 142. Linked List Cycle II 链表中的环 II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- LeetCode初级算法--链表02:合并两个有序链表
LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...
随机推荐
- OSG开发笔记(三十六):osg3.4.0基于windows平台msvc2017x64编译器编译并移植Demo
前言 本篇编译osg3.4.0的msvc2017x64版本,之前使用的都是mingw32版本. OSG编译 步骤一:下载解压 下载3.4.0版本. 步骤二:使用cmake配置 ...
- 在不同形式的for循环中使用break、continue、return的效果
我们在循环中,经常会有跳出循环,跳出本次循环继续下次循环等的场景,今天我们简单分享下.主要使用到的关键字是,break.continue.return.先将结果总结: ①在foreach中不能使用br ...
- IOS多线程之NSOperation(3)
IOS多线程之NSOperation(3) 操作优先级和服务质量 可以通过QueuePriority属性来设置operation在队列中的执行优先级 public enum QueuePriority ...
- Flutter 收起键盘
Flutter收起键盘 在根Widget中嵌套GestureDetector return GestureDetector( // 触摸收起键盘 behavior: HitTestBehavior.t ...
- Rapid SCADA v6安装常见问题
用了很多年的Rapid SCADA v5,现在官网已经推出了v6,就简单写一下有关v6的安装指南吧. 本指南面向Windows用户,不适用于linux用户 步骤 从官网下载Rapid SCADA最新的 ...
- Qt音视频开发26-监控画面各种图形绘制设计
一.前言 视频监控系统做到后面,逐渐需要搭配人工智能算法,将算法计算后的信息以OSD标签以及方框各种图形的信息显示到视频中,这种当然和OSD一样也是有两种方式,一种是源头就贴好了,一种是将结果发给软件 ...
- Kubernetes系列(一) - kubernetes入门基本概念
目录 1. 基本概念 1.1 什么是 Kubernetes 集群 1.2 Kubernetes集群资源组成: 1.3 无状态和有状态的区别 1.3.1 无状态服务 1.3.2 有状态服务 2. Kub ...
- IntelliJ IDEA2020永久激活破解教程(无限试用)
IntelliJ IDEA2020激活破解教程(无限试用) 鉴于想拥有一个十分舒适的编程环境,我特意将自己的电脑运行内存从4G扩展到12G,加装一个256G的固态作为C盘,并且将系统升级为Window ...
- c# 通过注册表判断有没有安装某个软件
private bool checkHasInstalledSoftWare(string displayName) { Microsoft.Win32.RegistryKey uninstallNo ...
- 工作流程调度器-DolphinScheduler
1.DolphinScheduler简介 Apache DolphinScheduler](https://dolphinscheduler.apache.org/)(目前处在孵化阶段)是一个分布式. ...