605 字
3 分钟
删除链表的倒数第 N 个结点

题目描述#

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

解题思路#

  1. 双指针技巧
    • 快指针先移动 N 步
    • 慢指针从头开始同步移动
  2. 虚拟头节点
    • 创建哑节点简化头节点删除操作
    • 始终返回 dummy.next 作为结果
  3. 同步移动
    • 快慢指针同步移动直至快指针到链表尾
    • 此时慢指针指向待删除节点的前驱
  4. 删除操作
    • 修改慢指针的 next 指向下下节点
    • 跳过需删除节点完成移除

关键洞察#

  1. 倒数位置转换
    • 倒数第 N 个 ≡ 正数第 (L-N+1) 个
    • 双指针避免显式计算链表长度 L
  2. 间距控制原理
    • 快指针领先 N 步形成固定间距
    • 当快指针到尾部时,慢指针恰在目标前驱
  3. 边界处理
    • 虚拟头节点统一处理头节点删除
    • 处理 N>L 的情况(快指针提前到 null)
  4. 一次遍历
    • 仅需单次遍历即可完成删除
    • 时间复杂度严格 O(L)

复杂度分析#

指标说明
时间复杂度O(L):L 为链表长度,只需一次遍历
空间复杂度O(1):仅使用常数空间存储指针
最佳情况O(1):当删除头节点时

代码实现#

/**
* 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) {
const dummy = new ListNode(0, head); // 创建虚拟头节点,指向head
let fast = dummy, slow = dummy;
// 快指针先走 n+1 步
for (let i = 0; i <= n; i++) {
fast = fast.next;
}
// 快慢指针同时移动,直到快指针到达链表末尾
while (fast) {
fast = fast.next;
slow = slow.next;
}
// 删除倒数第n个节点
slow.next = slow.next.next;
return dummy.next; // 返回真正的头节点
};

实际应用场景#

  1. 操作系统:内核调度中移除优先级最低的任务`
  2. 数据库管理:查询结果集中删除指定排名的记录`
  3. 实时监控:性能监控系统中移除响应最慢的节点`
  4. 游戏开发:玩家排行榜中移除指定名次的玩家`

相似题目#

删除链表的倒数第 N 个结点
https://website-truelovings-projects.vercel.app/posts/algorithms/删除链表的倒数第-n-个结点/
作者
欢迎来到StarSky的网站!
发布于
2025-08-23
许可协议
CC BY-NC-SA 4.0