news 2026/6/17 21:32:40

链表专题(四):一把尺子的智慧——「删除链表的倒数第 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/6/17 1:11:02

Docker日志暴增导致磁盘满载?快速定位并优化输出策略

第一章&#xff1a;Docker日志暴增现象的识别与影响在运行容器化应用时&#xff0c;Docker日志暴增是一个常见但容易被忽视的问题。当日志未加限制地持续写入&#xff0c;容器的日志文件可能迅速膨胀&#xff0c;占用大量磁盘空间&#xff0c;甚至导致宿主机磁盘满载&#xff0…

作者头像 李华
网站建设 2026/6/13 6:30:28

还在手动部署微服务?5个高并发场景下的Docker自动化脚本案例

第一章&#xff1a;微服务部署的挑战与Docker化转型在现代软件架构演进过程中&#xff0c;微服务因其高内聚、低耦合的特性被广泛采用。然而&#xff0c;随着服务数量的增长&#xff0c;传统部署方式暴露出环境不一致、依赖冲突、部署效率低下等问题。开发人员常遇到“在我机器…

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

Docker跨平台测试实战精要(专家20年经验倾囊相授)

第一章&#xff1a;Docker跨平台测试概述在现代软件开发中&#xff0c;确保应用程序在不同操作系统和环境中的一致性行为是质量保障的关键环节。Docker 通过容器化技术封装应用及其依赖&#xff0c;实现了“一次构建&#xff0c;随处运行”的理想模式&#xff0c;为跨平台测试提…

作者头像 李华
网站建设 2026/6/17 21:39:04

Docker日志实时监控实战:从输出到收集的完整链路搭建

第一章&#xff1a;Docker日志输出机制解析Docker 容器的日志输出是监控和调试容器化应用的关键环节。默认情况下&#xff0c;Docker 使用 json-file 日志驱动将容器的标准输出&#xff08;stdout&#xff09;和标准错误&#xff08;stderr&#xff09;以 JSON 格式写入本地文件…

作者头像 李华
网站建设 2026/6/15 2:39:41

【Docker日志输出效率提升】:90%工程师忽略的3个关键配置

第一章&#xff1a;Docker日志输出效率提升的背景与挑战在现代微服务架构中&#xff0c;容器化技术已成为应用部署的核心手段&#xff0c;而Docker作为最主流的容器运行时&#xff0c;其日志系统的性能直接影响着系统可观测性与运维效率。随着服务实例数量的快速增长&#xff0…

作者头像 李华
网站建设 2026/6/13 9:25:21

CES国际展会亮相计划:向全球推介中国AI技术创新

CES国际展会亮相计划&#xff1a;向全球推介中国AI技术创新 在2025年CES展会上&#xff0c;一款仅含15亿参数却能在数学推理与编程竞赛中击败数百倍规模模型的中国AI产品即将登场。它不追求通用对话的流畅性&#xff0c;也不擅长写诗讲故事&#xff0c;但当你抛出一个复杂的递归…

作者头像 李华