news 2026/5/4 0:12:43

链表专题(一):以退为进的智慧——「移除链表元素」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
链表专题(一):以退为进的智慧——「移除链表元素」

场景想象:你是一列火车的检票员,你的任务是把所有“没买票的乘客”(值为val的节点)踢下车。

  • 如果是中间的车厢没票:很简单,让前一节车厢直接连到后一节车厢,把中间那节甩掉就行。

  • 如果是**第一节车厢(火车头)**没票:这就麻烦了。因为火车头前面没有车厢了,你没法进行“跳过”操作。你需要特殊处理,换个新车头。

痛点:为了处理“头结点可能被删除”的情况,我们通常要写两套逻辑:一套处理头结点,一套处理中间节点。这很麻烦,而且容易写错。

解决方案:虚拟头结点 (Dummy Head)我们在原来的火车头前面,硬加一节**“假车厢”**。 这样一来,原来的火车头就变成了“第二节车厢”。所有节点(包括原来的头结点)都有了“前驱节点”。 我们就不用特殊分类讨论了,一套逻辑通杀所有情况!

力扣 203. 移除链表元素

https://leetcode.cn/problems/remove-linked-list-elements/

题目分析:

  • 输入:链表的头节点head,一个整数val

  • 目标:删除链表中所有满足Node.val == val的节点。

  • 输出:新的头节点。

例子:head = [1, 2, 6, 3, 4, 5, 6], val = 6

  • 移除所有的 6。

  • 结果:[1, 2, 3, 4, 5]

核心思维:虚拟头结点 + 遍历删除

  1. 创建 Dummylet dummy = new ListNode(0, head);

    • dummy.next指向原来的head

  2. 遍历指针cur:让cur指向dummy(站在假车厢上)。

  3. 判断与删除

    • cur.next(下一节车厢)的值。

    • 如果是目标值cur.next = cur.next.next;(跳过它!注意:此时 cur 不要动,因为新接上来的车厢可能还是目标值,要继续检查)。

    • 如果不是目标值cur = cur.next;(安全,cur 往前走一步)。

  4. 返回结果:返回dummy.next(因为dummy是假的,后面挂着的才是真的新链表)。

代码实现 (JavaScript)

JavaScript

/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * } */ /** * @param {ListNode} head * @param {number} val * @return {ListNode} */ var removeElements = function(head, val) { // 1. 创建虚拟头结点 // 它的值是多少不重要(0或者-1都行),关键是它的 next 要指向 head const dummy = new ListNode(0, head); // 2. 指针 cur 指向虚拟头结点 // 我们要通过 cur 去操作 cur.next let cur = dummy; // 3. 遍历链表 // 只要后面还有节点,就继续检查 while (cur.next !== null) { if (cur.next.val === val) { // 发现目标!执行删除操作 // 让 cur 的 next 指针跳过目标节点,直接连到下下个 cur.next = cur.next.next; // 重点细节:删除后,cur 不要往前走! // 因为新接上来的 cur.next 可能还是等于 val 的,下一轮循环要继续检查它 } else { // 不是目标,cur 安全前进一步 cur = cur.next; } } // 4. 返回真正的头结点 return dummy.next; };

深度对比:如果没有 Dummy Head 会怎样?

如果不加虚拟头结点,代码会变成这样:

JavaScript

// 【不推荐】没有 Dummy Head 的写法 var removeElements = function(head, val) { // 1. 先处理头结点连续是 val 的情况 // 比如 [6, 6, 6, 1], val=6。要把开头的 6 全删掉,head 才会变到 1 while (head !== null && head.val === val) { head = head.next; } // 2. 再处理非头结点 let cur = head; while (cur !== null && cur.next !== null) { if (cur.next.val === val) { cur.next = cur.next.next; } else { cur = cur.next; } } return head; };

你看,你需要额外写一个while循环专门去“清洗”头结点。 万一链表全是 6[6, 6, 6],删完变空了,你还得小心空指针报错。 用 Dummy Head 就可以把这两段逻辑统一,既优雅又不容易出错。

总结

这道题是链表的**“第一课”**。 请记住这个套路:凡是涉及“头结点可能会变”的操作(如删除、插入、翻转),无脑使用 Dummy Head,绝对没错。


下一题预告:反转链表

如果说这道题是热身,下一题LC 206. 反转链表就是真正的实战。

  • 题目:1 -> 2 -> 3 -> 4 -> 5

  • 变成:5 -> 4 -> 3 -> 2 -> 1

  • 这是一个需要你闭着眼睛都能写出来的算法。它是“K个一组翻转”、“回文链表”等所有高阶题目的基石。

准备好去扭转指针的方向了吗?

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

学霸同款2026 AI论文平台TOP8:毕业论文写作全测评

学霸同款2026 AI论文平台TOP8:毕业论文写作全测评 2026年学术写作工具测评:如何选出适合你的论文助手 随着人工智能技术在学术领域的深入应用,越来越多的学生开始依赖AI工具辅助毕业论文的撰写。然而,面对市场上琳琅满目的平台&am…

作者头像 李华
网站建设 2026/5/2 12:00:21

uniapp+vue学生宿舍购电电费缴纳系统 小程序

目录系统概述核心功能技术亮点应用价值关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&#x…

作者头像 李华
网站建设 2026/5/3 12:43:46

教育行业新应用:利用HeyGem创建AI教师讲解视频课程

教育行业新应用:利用HeyGem创建AI教师讲解视频课程 在今天的在线教育环境中,一个常见的困境是——课程内容需要频繁更新,但每改一次就得重新拍摄、剪辑、配音,整个流程耗时又费力。尤其是面对多地区、多语言、多版本的教学需求时&…

作者头像 李华
网站建设 2026/4/28 13:10:42

uniapp+vue微信小程序的银行员工绩绩效考核系统 理财产品商城系统-vue

目录银行员工绩效考核与理财产品商城系统摘要关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/5/2 8:35:39

[精品]基于微信小程序的流浪动物救助领养平台 UniApp

文章目录 项目实现效果图所需技术栈文件解析微信开发者工具HBuilderXuniappmysql数据库与主流编程语言登录的业务流程的顺序是:毕设制作流程系统性能核心代码系统测试详细视频演示源码获取 项目实现效果图 项目编号:035 所需技术栈 小程序…

作者头像 李华
网站建设 2026/5/1 18:42:00

[精品]基于微信小程序的企业内部订餐小程序 UniApp

文章目录 项目实现效果图所需技术栈文件解析微信开发者工具HBuilderXuniappmysql数据库与主流编程语言登录的业务流程的顺序是:毕设制作流程系统性能核心代码系统测试详细视频演示源码获取 项目实现效果图 项目编号:045 所需技术栈 小程序…

作者头像 李华