当前位置: 首页 > news >正文

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

当然可以!这段代码是 LeetCode 中一个非常经典的题目:删除链表的倒数第 N 个节点(Remove Nth Node From End of List)


🧩题目要求:

给定一个单链表,删除链表的倒数第 n 个节点,并返回链表的头节点。


📌题解思路:

使用 双指针法(快慢指针) + 虚拟头节点(dummy node)


🧱代码分析:

ListNode dummy = new ListNode(0);
dummy.next = head;
  • 创建一个虚拟头节点 dummy,它的 next 指向 head

  • 用于简化边界处理,比如删除第一个节点时不用单独判断。


if (head == null || head.next == null) return null;
  • 如果链表为空或者只有一个节点,直接返回 null,因为删掉最后一个节点之后就没有节点了。


ListNode fast = head;
ListNode slow = head;
while (--n > 0) fast = fast.next;
  • 初始化快慢指针。

  • 快指针先走 n - 1 步(因为一开始两个指针都在 head,这相当于间隔 n 个节点)。


while (fast.next != null) {
    fast = fast.next;
    slow = slow.next;
    dummy = dummy.next;
}
  • 快指针和慢指针一起走,直到快指针走到最后一个节点。

  • 此时 slow 指向的是 要被删除节点的前一个节点

  • 这段代码的问题是:你用了 dummy = dummy.next;,这其实让 dummy 跟着慢指针跑了,不太合理。dummy 应该是一直指向链表头的哨兵,不该动。


if (slow == head) return slow.next;
  • 如果要删除的是第一个节点,直接返回 head.next


dummy.next = slow.next;
return head;
  • 正常情况下,跳过当前的 slow 节点,完成删除。


⚠️这段代码的问题:

  1. dummy 不应该动。你写了 dummy = dummy.next;,这是不对的,dummy 应该固定。

  2. 判断 slow == head 有点冗余,用 dummy 可以避免这种边界判断。

  3. 实际上,只需要固定 dummy,fast 从 dummy 开始走 n 步,再 fast 和 slow 一起走到尾部。


✅更标准写法如下:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode fast = dummy;
        ListNode slow = dummy;

        // fast 先走 n 步
        for (int i = 0; i < n; i++) {
            fast = fast.next;
        }

        // 然后 fast 和 slow 一起走,直到 fast 到尾
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        // 删除 slow 的下一个节点
        slow.next = slow.next.next;

        return dummy.next;
    }
}

🌟总结:

  • 使用 dummy 可以避免很多边界问题。

  • 快慢指针配合可以高效定位到倒数第 N 个节点。

  • 本题的核心技巧是:让 fast 先走 n 步,再一起走

好的!我们来画一个简单的链表图,帮助你理解 快慢指针删除倒数第 N 个节点 的过程。


🧷 假设链表如下(5个节点):

索引:     1 →  2 →  3 →  4 →  5
节点:   [1]→[2]→[3]→[4]→[5]→null

我们要 删除倒数第 2 个节点(也就是值为 4 的节点)。


📌 添加一个虚拟头节点 dummy:

dummy → [1]→[2]→[3]→[4]→[5]→null

初始状态:

fast 和 slow 都指向 dummy

🚶‍♂️fast 先走 n 步(n = 2):

第一步:

fast → [1]   slow → dummy

第二步:

fast → [2]   slow → dummy

🏃‍♂️fast 和 slow 一起走,直到 fast 到达最后一个节点:

第一轮:

fast → [3]   slow → [1]

第二轮:

fast → [4]   slow → [2]

第三轮:

fast → [5]   slow → [3]

结束循环,此时:

slow → [3]

✂️删除 slow 的下一个节点:

slow.next = slow.next.next;

也就是把 [4] 从链表中跳过,指向 [5]

dummy → [1]→[2]→[3]→[5]→null

✅最终返回 dummy.next 即是新的头节点:

[1]→[2]→[3]→[5]→null

相关文章:

  • OpenCv(七)——模板匹配、打包、图像的旋转
  • 在Unity中实现《幽灵行者》风格的跑酷动作
  • Linux 递归查找并删除目录下的文件
  • HTML基础教程:创建双十一购物狂欢节网页
  • VUE中数据绑定之OptionAPI
  • C语言基础17
  • ebpf: CO-RE, BTF, and Libbpf(一)
  • 我的第一个正式开源小项目:内网文件传输工具
  • 2025 年上海保安员职业资格考试深度剖析​
  • 大模型RAG项目实战-知识库问答助手v1版
  • PDF 中提取数学公式
  • 通过安装Windows 11英文版 解决组件问题解决中文版中无法修复组件的问题
  • AI前端组件库Ant DesIgn X
  • Cribl 新建Datatype
  • 人工智能 和 线性代数
  • Skyeye 云智能制造办公系统 - 云校园 VUE 版本 v3.15.16 发布
  • C++11QT复习 (十五)
  • Elixir语言的移动应用安全
  • 谈谈我所了解的hash
  • 哑铃图:让数据对比一目了然【Dumbbell Chart】
  • 合伙做网站怎么分配股权/百度推广外包
  • 网站外链建设大揭秘/北京seo公司有哪些
  • 网上推广赌博/朝阳seo建站
  • 网站后台都需要什么软件做/每天新闻早知道
  • 网站建设案例新闻/公司运营策划营销
  • 家用电脑怎么做网站/河南企业站seo