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;
    }
}
相关推荐
m沐沐5 小时前
【深度学习】YOLOv2目标检测算法——改进点、网络结构与聚类先验框解析
人工智能·pytorch·深度学习·算法·yolo·目标检测·transformer
不会就选b5 小时前
算法日常・每日刷题--<链表>3
数据结构·算法·链表
geovindu6 小时前
go: Iterative Algorithms
开发语言·后端·算法·golang·迭代算法
Zachery Pole8 小时前
CCF-CSP备战NO.7【队列】
算法
闪电悠米8 小时前
力扣hot100-48.旋转图像-转置翻转详解
算法·leetcode·职场和发展
满天星83035778 小时前
【算法】最长递增子序列(三种解法)
算法
啦啦啦啦啦zzzz9 小时前
算法:贪心算法
c++·算法·leetcode·贪心算法
清泓y11 小时前
RAG 技术
算法·ai
阿慧今天瘦了嘛11 小时前
计算机组成原理概述:从硬件到软件的桥梁
计算机网络·算法
网站优化(SEO)专家11 小时前
SEO核心算法拆解:网站排名快速提升的武林秘籍!
算法·搜索引擎·网站排名·核心算法