news 2026/8/23 23:27:49

【每日算法】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/8/23 23:18:18

LangFlow支持多种编程语言节点混合编排实战

LangFlow 多语言节点混合编排实战:打破技术栈壁垒的AI流程构建 在企业级AI系统开发中,一个常见的困境是:算法团队用Python写模型,后端服务由Java支撑,前端又有大量JavaScript文本处理逻辑。当我们要构建一个完整的智能…

作者头像 李华
网站建设 2026/8/24 14:57:52

基于springboot + vue高校宿舍管理系统

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

作者头像 李华
网站建设 2026/8/23 16:28:52

Golang中解析SQL语句为JSON格式常用的库介绍

在Go中解析SQL语句为JSON格式,常用的库有以下几种: 1. sqlparser(最常用) GitHub: https://github.com/xwb1989/sqlparser import ("github.com/xwb1989/sqlparser""encoding/json" )func parseSQLToJSON(sql…

作者头像 李华
网站建设 2026/8/24 2:52:45

基于Android的固定资产借用管理平台系统(源码+lw+部署文档+讲解等)

课题介绍本课题聚焦企事业单位、高校固定资产借用流程繁琐、归还提醒缺失、资产追踪困难的痛点,设计实现基于 Android 的固定资产借用管理平台。系统以 Java 为核心开发语言,基于 Android 原生框架搭建移动端应用,搭配轻量后端服务架构&#…

作者头像 李华
网站建设 2026/8/24 15:02:45

AI智能体落地实战指南:揭秘七大核心陷阱与解决方案,程序员小白必备的避坑宝典!

简介 本文揭示企业AI智能体落地的七大陷阱及解决方案:从业务场景切入而非为AI而AI、构建数据基础、采用成熟技术、确保安全可控、重塑人机协作、建立持续运维机制和规划能力中台。成功落地不仅是技术采购,更是运营模式和组织能力的重构,需以业…

作者头像 李华
网站建设 2026/8/24 15:02:14

Windows下深度学习环境配置全指南

Windows下深度学习环境配置全指南 在尝试跑通第一个中文文本分类模型时,你是否曾因为“CUDA not available”而反复重装驱动?或者在安装PaddleOCR时被复杂的依赖关系搞得焦头烂额?对于大多数刚进入深度学习领域的开发者来说,真正…

作者头像 李华