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

leetcode.cn/problems/re...

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

示例 1:

ini 复制代码
输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]

示例 2:

ini 复制代码
输入: head = [1], n = 1
输出: []

示例 3:

ini 复制代码
输入: head = [1,2], n = 1
输出: [1]

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

进阶: 你能尝试使用一趟扫描实现吗?

双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。

思路是这样的,但要注意一些细节。

分为如下几步:

  • 首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: 链表:听说用虚拟头节点会方便很多?
  • 定义fast指针和slow指针,初始值为虚拟头结点,如图:
  • fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作),如图:
  • fast和slow同时移动,直到fast指向末尾,如题: //图片中有错别词:应该将"只到"改为"直到"
  • 删除slow指向的下一个节点,如图:
kotlin 复制代码
class Solution {
    fun removeNthFromEnd(head: ListNode?, n: Int): ListNode? {
        //新建一个虚拟头节点指向head
        val dummyNode = ListNode(0)
        dummyNode.next = head
        //快慢指针指向虚拟头节点
        var fastNode: ListNode? = dummyNode
        var slowNode: ListNode? = dummyNode

        // 只要快慢指针相差 n 个结点即可
        for (i in 0..<n) {
            fastNode = fastNode?.next
        }

        while (fastNode?.next != null) {
            fastNode = fastNode.next
            slowNode = slowNode?.next
        }

        // 此时 slowIndex 的位置就是待删除元素的前一个位置。
        // 具体情况可自己画一个链表长度为 3 的图来模拟代码来理解
        slowNode?.next = slowNode.next?.next

        return dummyNode.next
    }
}
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

递归解法:

java 复制代码
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 创建一个新的哑节点,指向原链表头  
        ListNode s = new ListNode(-1, head);
        // 递归调用remove方法,从哑节点开始进行删除操作  
        remove(s, n);
        // 返回新链表的头(去掉可能的哑节点)  
        return s.next;
    }
    
    public int remove(ListNode p, int n) {
        // 递归结束条件:如果当前节点为空,返回0  
        if (p == null) {
            return 0;
        }
        // 递归深入到下一个节点  
        int net = remove(p.next, n);
        // 如果当前节点是倒数第n个节点,进行删除操作  
        if (net == n) {
            p.next = p.next.next;  
        }
        // 返回当前节点的总深度  
        return net + 1;
    }
}
相关推荐
武子康2 小时前
Qwen-Drive 到底是什么:4B 级 VLM 如何成为驾驶策略底座
人工智能·算法·机器学习
zh_xuan3 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长3 小时前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维
早起CaiCai4 小时前
【2023-01 OM】利用深度学习算法融合异质观测实现海洋场降尺度
人工智能·深度学习·算法
梦里寻码5 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
猿人谷5 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
青少儿编程课堂7 小时前
蓝桥杯青少组图形化 STEMA 省考(报名倒计时·11/22开考)+ 全国青少年信息素养大赛 2026—2027赛季 + 电子学会图形化考级:校园华容道大闯关
c++·python·算法·bfs·信息学竞赛
在猴站学算法8 小时前
(《统计学习方法》(第2版) 李航)第2章 感知机算法
学习·算法·机器学习·统计学习
Rainmicro8 小时前
【无标题】
java·数据库·算法