news 2026/4/23 0:35:18

链表专题(四):一把尺子的智慧——「删除链表的倒数第 N 个结点」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
链表专题(四):一把尺子的智慧——「删除链表的倒数第 N 个结点」

场景想象:

你手里有一根链表,但你不知道它有多长(不能直接得到 length)。

任务是:找到倒数第 N 个节点,把它删掉。

  • 如果是数组,我们可以直接算下标length - N

  • 但链表是单向的,我们不知道终点在哪。

  • 笨办法:先跑一趟量长度L,再跑一趟去L - N的位置。虽然是 $O(N)$,但遍历了两次。

  • 聪明办法(快慢指针):

    想象你手里有一把长度为 N 的“尺子”(或者一根棍子)。

    1. 快指针先跑N步(撑开尺子)。

    2. 然后让快指针慢指针同时往后移。

    3. 快指针碰到链表尽头(null)时,慢指针(尺子的另一头)正好就停在了倒数第 N 个节点的位置!

核心痛点:

要删除一个节点,我们需要找到它的前一个节点 (Pre)。

所以,我们的“尺子”实际上要稍微再长一点,或者让快指针多走一步,这样慢指针才能停在目标节点的前一位。

力扣 19. 删除链表的倒数第 N 个结点

https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

题目分析:

  • 输入:链表头head,整数n

  • 目标:删除倒数第n个节点。

  • 输出:新头节点。

例子:1 -> 2 -> 3 -> 4 -> 5,n = 2

  • 倒数第 2 个是4

  • 删除后:1 -> 2 -> 3 -> 5

核心思维:虚拟头结点 + 快慢指针 (Gap法)

  1. 虚拟头结点 (Dummy)

    • 为什么又要它?因为如果要删的是倒数最后一个(也就是正数第一个,头结点),没有 Dummy 会很麻烦。

  2. 快指针先跑n + 1

    • 为什么是n + 1

    • 因为我们希望当快指针指向null(越界)时,慢指针正好停在倒数第 n 个节点的前一个

    • 这样我们才能执行slow.next = slow.next.next

代码实现 (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} n * @return {ListNode} */ var removeNthFromEnd = function(head, n) { // 1. 虚拟头结点:防止删除的是头结点(比如 list=[1], n=1) const dummy = new ListNode(0, head); // 2. 定义快慢指针,初始都指向 dummy let slow = dummy; let fast = dummy; // 3. 让快指针先走 n + 1 步 // 目的:拉开 n+1 的间距。这样当 fast 走到 null 时,slow 正好在目标的前一位 for (let i = 0; i <= n; i++) { fast = fast.next; } // 4. 双指针同时移动 // 只要 fast 还没掉出悬崖(null),就一起往后挪 while (fast !== null) { slow = slow.next; fast = fast.next; } // 5. 此时 slow 指向的是“倒数第 n 个节点”的【前驱节点】 // 执行删除操作 slow.next = slow.next.next; return dummy.next; };

深度模拟

假设list = [1, 2, 3, 4, 5],n = 2(删除 4)。

  • 初始dummy -> 1 -> 2 -> 3 -> 4 -> 5 -> null

  • Fast 先跑 3 步 (n+1)

    • 0步: dummy

    • 1步: 1

    • 2步: 2

    • 3步: 3

    • 此时fast在 3,slow在 dummy。

  • 一起跑

    • Round 1:fast->4,slow->1

    • Round 2:fast->5,slow->2

    • Round 3:fast->null,slow->3

  • 停!fast是 null 了。

  • 操作slow现在指着 3。

    • slow.next是 4 (目标)。

    • slow.next = slow.next.next(也就是 5)。

    • 链表变成1 -> 2 -> 3 -> 5。完美!

总结

这道题是**“固定间距双指针”**的教科书级应用。

  • 关键点:只要看到“倒数第 K 个”,马上反应过来 ->让快指针先走 K 步

  • 细节:为了方便删除,我们通常让快指针多走一步(或者判断条件改为fast.next !== null),目的是拿到前驱节点


下一题预告:相交链表

刚才我们用两个指针一前一后跑。

下一题 LC 160. 相交链表(专题五),我们要让两个指针在两条不同的路上跑。

  • 题目:给你两个链表 A 和 B,它们在某个节点汇合了(变成 Y 字形)。请你找到这个交点。

  • 难点:A 和 B 长度不一样,直接遍历会错开,怎么让它们在终点相遇?

  • 技巧:“走过你走的路”—— 极其浪漫的解法。

准备好继续了吗?

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

网盘直链下载助手+AI模型?双工具联动提升资源获取效率

轻量模型遇上极速部署&#xff1a;VibeThinker-1.5B 与镜像分发的协同革命 在 AI 模型越来越“重”的今天&#xff0c;动辄数百亿参数、依赖云端 API、按 Token 计费的使用模式&#xff0c;正在让许多个人开发者和研究者望而却步。尤其是在数学推理、算法编程这类高强度任务中…

作者头像 李华
网站建设 2026/4/23 0:33:34

‌低代码测试平台避坑指南:我用Bubble构建的自动化系统,节省了40%人力‌——开源流程设计模板+权限配置清单

引言&#xff1a;低代码测试浪潮下的效率革命 在数字化转型加速的2026年&#xff0c;测试团队面临迭代提速与资源紧缩的双重压力。传统脚本自动化依赖高技能人力&#xff0c;而低代码平台如Bubble通过可视化开发&#xff0c;让测试人员能以“拖拽逻辑块”方式快速构建系统。本…

作者头像 李华
网站建设 2026/4/23 0:35:18

你不可不知的Docker隐性故障:健康检查超时背后的3个陷阱

第一章&#xff1a;Docker健康检查失败的常见表象在使用 Docker 部署容器化应用时&#xff0c;健康检查&#xff08;Health Check&#xff09;是确保服务稳定运行的重要机制。当健康检查失败时&#xff0c;容器可能被标记为非健康状态&#xff0c;进而触发编排系统&#xff08;…

作者头像 李华
网站建设 2026/4/22 6:48:45

数据安全管控平台核心技术:国内实力厂商全景梳理

在强监管政策与数字化转型的双重驱动下&#xff0c;数据安全管控已从分散的单点防护升级为体系化的平台化治理&#xff0c;核心技术的迭代演进成为厂商竞争力的核心支撑。随着《数据安全法》《网络数据安全管理条例》的深度落地&#xff0c;企业对管控平台的需求已从基础的合规…

作者头像 李华
网站建设 2026/4/16 10:51:26

WSL2下运行VibeThinker-1.5B:Windows用户的最佳实践

WSL2下运行VibeThinker-1.5B&#xff1a;Windows用户的最佳实践 在如今AI模型动辄数百亿参数、训练成本高达百万美元的时代&#xff0c;普通开发者和学生是否还有机会真正“拥有”一个能解决实际问题的智能助手&#xff1f;答案是肯定的——只要你愿意尝试轻量级但高度专精的小…

作者头像 李华
网站建设 2026/4/20 17:06:01

Vue3 组件通信全解析:技术细节、适用场景与性能优化

在 Vue3 的前端开发体系中&#xff0c;组件是构建复杂应用的核心单元。随着应用规模扩大&#xff0c;组件间的数据传递、状态共享及事件联动成为开发核心诉求。组件通信的合理性直接影响代码的可维护性、可读性与运行性能&#xff0c;不合理的通信方式可能导致数据流向混乱、性…

作者头像 李华