news 2026/5/1 9:59:12

【每日算法】LeetCode142. 环形链表 II

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【每日算法】LeetCode142. 环形链表 II

对前端开发者而言,学习算法绝非为了“炫技”。它是你从“页面构建者”迈向“复杂系统设计者”的关键阶梯。它将你的编码能力从“实现功能”提升到“设计优雅、高效解决方案”的层面。从现在开始,每天投入一小段时间,结合前端场景去理解和练习,你将会感受到自身技术视野和问题解决能力的质的飞跃。------ 算法:资深前端开发者的进阶引擎

环形链表 II:从"龟兔赛跑"到链表环检测的工程启示

1. 题目描述

1.1 问题背景

给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null

链表节点定义如下:

classListNode{constructor(val){this.val=val;this.next=null;}}

1.2 示例说明

输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点

2. 问题分析

2.1 链表环的检测

在前端开发中,链表结构不如数组常见,但在某些场景下(如虚拟DOM的Fiber架构、React Hooks的链表实现)有重要应用。环形链表检测是链表操作中的经典问题,其核心挑战在于:

  1. 如何判断链表是否有环:简单遍历会陷入无限循环
  2. 如何找到环的起点:环的检测和起点定位需要不同策略

2.2 实际应用场景

  1. 内存泄漏检测:检测JavaScript对象间的循环引用
  2. 状态管理:Redux等状态管理库中的循环依赖检测
  3. 构建工具:Webpack等模块打包工具中的循环依赖分析
  4. UI框架:React Fiber树中循环引用检测

3. 解题思路

3.1 哈希表法(直观解法)

使用哈希表(JavaScript的Set或Map)存储已访问的节点,当遇到重复节点时即为环的起点。

时间复杂度:O(n)
空间复杂度:O(n)

3.2 快慢指针法(Floyd判圈算法)

使用两个指针,一个慢指针(每次移动一步),一个快指针(每次移动两步)。该算法分为两个阶段:

  1. 检测阶段:判断链表是否有环
  2. 定位阶段:找到环的入口节点

数学原理:设从head到环入口距离为a,环入口到相遇点距离为b,相遇点到环入口距离为c。当快慢指针相遇时,慢指针走了a+b,快指针走了a+b+n(b+c)。由于快指针速度是慢指针2倍,可得:2(a+b) = a+b+n(b+c) => a = (n-1)(b+c) + c

时间复杂度:O(n)
空间复杂度:O(1)

3.3 立flag法(标记法)

遍历链表,给访问过的节点打上标记(设置一个标志位),当再次遇到已标记的节点时,即为环的起点。

时间复杂度:O(n)
空间复杂度:O(1)(如果不考虑添加的标记属性)

4. 各思路代码实现

4.1 哈希表实现

/** * 哈希表解法 * @param {ListNode} head * @return {ListNode} */constdetectCycleWithHash=function(head){if(!head||!head.next)returnnull;constvisited=newSet();letcurrent=head;while(current){if(visited.has(current)){returncurrent;// 找到环的起点}visited.add(current);current=current.next;}returnnull;// 无环};

4.2 快慢指针实现

/** * 快慢指针解法(Floyd算法) * @param {ListNode} head * @return {ListNode} */constdetectCycleWithTwoPointers=function(head){if(!head||!head.next)returnnull;letslow=head;letfast=head;// 第一阶段:检测是否有环while(fast&&fast.next){slow=slow.next;fast=fast.next.next;if(slow===fast){// 第二阶段:寻找环的起点letpointer=head;while(pointer!==slow){pointer=pointer.next;slow=slow.next;}returnpointer;// 环的起点}}returnnull;// 无环};

4.3 立flag法实现

/** * 立flag法(修改原链表) * @param {ListNode} head * @return {ListNode} */constdetectCycleWithFlag=function(head){letcurrent=head;while(current){if(current.flag){returncurrent;}current.flag=true;current=current.next;}returnnull;};

5. 各实现思路的复杂度、优缺点对比

方法时间复杂度空间复杂度优点缺点前端适用场景
哈希表法O(n)O(n)思路直观,易于理解;一次遍历即可找到环起点需要额外存储空间;对内存敏感的场景不适用快速原型开发;小规模数据检测;调试工具开发
快慢指针法O(n)O(1)常数空间复杂度;算法优雅高效;实际应用广泛理解难度较高;需要数学推导验证性能敏感应用;内存受限环境;大规模链表操作
立flag法O(n)O(1)*实现简单;无需额外数据结构污染原数据;可能与其他属性冲突临时性检测;允许修改数据的场景

注:立flag法的空间复杂度为O(1)是假设我们不考虑添加的flag属性所占空间。实际上,这会修改每个节点的内存占用。

6. 总结

6.1 核心要点

  1. 快慢指针法是解决环形链表问题的标准答案,其O(1)的空间复杂度在大规模数据处理中至关重要
  2. 哈希表法在面试中可以作为备用方案展示,体现解决问题的多样性
  3. 立flag法虽然实现简单,但会污染原数据,在实际工程中需谨慎使用

6.2 前端工程实践

  1. 虚拟DOM diff算法:React Fiber架构使用链表结构管理组件树,环检测可防止无限更新循环
  2. 依赖关系分析:Webpack模块解析中,环检测可提前发现循环依赖并报错
  3. 状态管理:在复杂的状态流转中,检测状态更新的循环依赖
  4. 内存泄漏监控:在Chrome DevTools中,可通过类似算法检测JavaScript对象间的循环引用
  5. 数据结构选择:在实际项目中,根据是否允许修改原数据选择合适的算法

6.3 选择建议

  • 面试场景:优先展示快慢指针法,可补充哈希表法展示知识广度
  • 生产环境
    • 如果允许修改数据且数据规模小,可使用立flag法
    • 如果需要保持数据纯净,使用快慢指针法
    • 如果数据规模大且对内存敏感,必须使用快慢指针法
    • 调试场景可使用哈希表法,便于理解和验证

6.4 学习建议

对于前端开发者,理解这类算法的价值不仅在于解决LeetCode题目,更在于:

  1. 提升抽象思维能力:将具体问题转化为数学模型
  2. 优化代码性能:在大型前端应用中,合理的数据结构和算法能显著提升性能
  3. 解决复杂业务问题:如表单校验依赖关系、工作流状态机等场景
  4. 培养工程思维:根据实际约束(内存、性能、数据纯度)选择合适方案

算法思维是前端开发者从"视图构建者"向"系统架构师"转变的关键能力。每天花少量时间研究一个算法问题,结合前端实际场景思考应用,长期积累将带来技术视野的质的飞跃。记住,不仅要掌握最优解,还要理解各种解法的适用场景和权衡取舍,这在实际工程中尤为重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 8:35:22

Axure设计的数据大屏:以泾县农村经济分析大屏为例

随着信息技术的飞速发展,数据在各个领域中发挥着越来越重要的作用。数据大屏作为一种高效的数据展示方式,能够帮助用户快速、直观地理解和分析复杂的数据信息。Axure作为一款专业的快速原型设计工具,为数据大屏的设计提供了强大的支持。本文将…

作者头像 李华
网站建设 2026/5/1 7:27:28

Qwen3-8B集成MCP实现动态工具调用

Qwen3-8B集成MCP实现动态工具调用 在智能体(Agent)技术加速落地的今天,一个核心问题正被反复追问:如何让大模型真正“动手做事”? 我们早已不满足于模型仅仅“回答问题”。用户需要的是能查天气、订机票、读邮件、操作…

作者头像 李华
网站建设 2026/4/23 20:25:29

独立站第三方对接:运营效率与体验提升的核心环节

在搭建独立站的过程中,第三方对接是不可或缺的一环。语言、支付、物流、仓库、ERP 等环节的对接,都需要商家精心策划与安排。通过合理的第三方对接,可实现:提高独立站运营效率降低运营成本提升用户体验一、多语言支持对接为吸引全…

作者头像 李华
网站建设 2026/5/1 6:26:24

基于springboot + vue 12306购票管理系统(源码+数据库+文档)

中国铁路 12306购票管理 目录 基于springboot vue中国铁路 12306购票管理系统 一、前言 二、系统功能演示 详细视频演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue中国铁…

作者头像 李华
网站建设 2026/5/1 6:29:25

通过图片获取商品信息,item_search_img调用指南

通过图片获取商品信息(如item_search_img类API调用)需结合电商平台开放接口与图像识别技术,以下是系统性操作指南:1. 核心平台与API选择京东开放平台接口:item_search_img(按图搜索商品)流程&am…

作者头像 李华