链表找环:Floyd 判圈算法(LeetCode 141 142 )

发布时间:2026/10/11 1:27:28

链表找环:Floyd 判圈算法(LeetCode 141  142 ) 在链表相关的算法题中「判断链表是否有环」以及「寻找入环点」是两道极其经典的题目。它们不仅考察了对指针的操作更蕴含了一个巧妙的数学原理——Floyd判圈算法龟兔赛跑算法。一、 LeetCode 141判断链表中是否有环题目链接题目要求给定一个链表判断链表中是否有环。1. 核心思想快慢指针龟兔赛跑如果在直线跑道上跑得快的人一定会先到达终点但如果是在环形跑道上跑得快的人最终一定会从背后追上套圈跑得慢的人。我们设定两个指针慢指针slow每次移动 1 步。快指针fast每次移动 2 步。2. 逻辑推演无环情况fast 指针会率先走到链表末尾nullptr此时循环结束返回 false。有环情况fast 指针进入环后会在环内不断循环。由于 fast 每次比 slow 多走 1 步两者的距离会不断缩小最终必定在环内某处相遇slow fast此时返回 true。3. 代码实现 (C)class Solution { public: bool hasCycle(ListNode *head) { if (head nullptr || head-next nullptr) return false; ListNode *slow head; ListNode *fast head; while (fast ! nullptr fast-next ! nullptr) { slow slow-next; // 慢指针走一步 fast fast-next-next; // 快指针走两步 if (slow fast) return true; // 相遇即有环 } return false; } };复杂度分析时间复杂度 O(N)空间复杂度 O(1)。二、 LeetCode 142寻找入环的第一个节点题目链接题目要求如果链表有环返回入环的第一个节点无环则返回 null。这道题在 141 的基础上增加了难度不仅要知道有没有环还要精准定位环的入口。这需要用到一段精妙的数学推导。1. 变量定义假设从头节点到入环点的距离为 a从入环点到快慢指针相遇点的距离为 b从相遇点再回到入环点的距离为 c。环的总长度为 b c。2. 数学证明为什么相遇后从头走和从相遇点走会碰头当快慢指针相遇时慢指针slow走过的路程a b快指针fast走过的路程a b n * (b c) n 为快指针在环内转的圈数n 1因为快指针的速度是慢指针的两倍所以相同时间内快指针走过的路程是慢指针的 2 倍2 * (a b) a b n * (b c)化简等式a b n * (b c) a n * (b c) - b a (n - 1) * (b c) c结论解读(n - 1) * (b c) 代表在环内转了 (n-1) 个整圈。这说明从头节点走到入环点的距离a等于从相遇点走到入环点的距离c加上转了若干整圈。3. 算法设计基于上述数学结论我们可以在快慢指针相遇后开启第二阶段让一个指针 ptr 重新回到头节点 head。让 ptr 和相遇点的 slow 指针同时出发每次各走 1 步。由于 a 的长度等同于 c加上整数圈这两个指针必定会在入环点相遇。4. 代码实现 (C)class Solution { public: ListNode *detectCycle(ListNode *head) { if (head nullptr || head-next nullptr) return nullptr; ListNode *slow head; ListNode *fast head; while (fast ! nullptr fast-next ! nullptr) { slow slow-next; fast fast-next-next; if (slow fast) { // 1. 找到相遇点 ListNode *ptr head; // 2. 指针回到头节点 // 3. 两指针同速前进相遇点即为入环点 while (ptr ! slow) { ptr ptr-next; slow slow-next; } return ptr; } } return nullptr; // 无环 } };复杂度分析时间复杂度 O(N)空间复杂度 O(1)。
延伸阅读

更多相关文章

2026/10/11 1:22:28

智能工厂建设方案全解析:从架构到落地避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 1:22:28

Buzz 离线语音转文字:导入音频,一键生成字幕

Buzz 离线语音转文字:导入音频,一键生成字幕 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 会议录音…

2026/10/11 2:32:30

JVM垃圾回收面试题全解析:从对象判活到三色标记与收集器选型

JVM垃圾回收面试题,几乎可以说是Java面试的“必考大题”。无论校招还是社招,面试官基本都会从内存模型切入,一路追问到垃圾回收的算法、收集器、调优参数。很多候选人基础题背得滚瓜烂熟,一到“为什么这样设计”“两者对比怎么选”…

2026/10/11 2:32:30

Niagara轻量发射器优化实战:从粒子模块减法到渲染性能提升

Niagara的Lightweight Emitters,这件事我最初是从一次移动端掉帧事故开始的。当时接到一个模拟项目X的优化任务,场景里有一批体积烟雾、火花和扬尘效果,总共十几个Niagara发射器,在某中端手机上帧耗时直接飙到11ms以上&#xff0c…

2026/10/11 2:32:30

AnyPS5串流实战:跨平台游戏串流原理、配置与延迟优化指南

1. 从“AnyPS5”这个标题说起:一个跨平台串流工具的设计思路第一次看到“AnyPS5”这个标题,我脑子里蹦出来的第一个念头是:这大概率又是一个围绕主机游戏串流做文章的项目。果不其然,稍微琢磨一下就能明白,它想解决的核…

2026/10/11 2:27:30

ONNX Runtime 模型部署全链路实战:从导出到量化与跨平台优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑