力扣19删除链表的倒数第 N 个结点:思路分析+图文全解+方法总结(快慢指针法递归法)+深入思考

文章目录

  • 第一部分:题目描述
  • 第二部分:代码实现
    • 2.1 快慢指针法
    • 2.2 递归

第一部分:题目描述

🏠 链接:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

⭐ 难度:中等

image-20230513080722075

第二部分:代码实现

2.1 快慢指针法

快慢指针,p1 指向待删节点的上一个,p2 先走 n + 1 步。

步骤:

  1. 快慢指针都指向哨兵 sentinel (创建sentinel节点,将 sentinel 的下一个节点设置为头节点 head)。
  2. fast 向后移动 n+1 个位置,使得 slow 与 fast 保持了 n+1 个距离。
  3. fast 和 slow一起向后移动(移动相同距离),直到 fast 到最后一个节点的下一个节点( null )。fast 和 slow 始终保持着 n+1 个位置的距离。要删除的倒数的第 n 个节点,就是 slow 的下一个节点。
  4. 删除节点就是将 改变 slow 的下一个节点为 slow 的下下个节点。
  5. 返回真正的头节点,就是 sentinel 的下一个节点。

图解分析:

已知链表 1 -> 2 -> 3 -> 4 -> 5,需要删除倒数第 2 个节点(n = 2)

image-20230514001541285

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 链表:sentinel -> 1 -> 2 -> 3 -> 4 -> 5
        // n = 2,应当删除节点4

        // 哨兵节点,作为伪头节点
        ListNode sentinel = new ListNode(-1, head);
        // 快指针
        ListNode fast = sentinel;
        // 慢指针
        ListNode slow = sentinel;


        // 先将 快指针 移动到 慢指针 n+1 个位置后
        // 移动后 fast 指向 3,slow 指向 sentinel
        while (n > -1) {
            fast = fast.next;
            n--;
        }

        // 将快慢指针向后移动,知道 快指针到了最后一个节点的下一个节点 null
        // 此时 慢指针 指向节点的 下一个节点就是待删除的节点 (val = 3)
        while (fast != null) {
            slow = slow.next;
            fast = fast.next;
        }

        // 将当前慢指针指向节点的下一个节点更改为 待删除节点的下一个节点
        // 那么此时 3 -> 5
        slow.next = slow.next.next;

        // 返回真正的头节点
        return sentinel.next;
    }
}

为什么要设置一个sentinel

Answer:主要是考虑待删除的节点正好是头节点 head 的情况。我们知道在单链表中我们想要删除一个节点需要依靠它的上一个节点,而头节点head没有上一个节点,因此我们暂时给 head 前面加一个伪头节点 sentinel 指向 head。这样就能像其它节点一样通过待删除节点的上一个节点来删除待删除的节点。

2.2 递归

思路:写一个递归函数,用来返回下一个节点的倒数序号。

recursion(ListNode p=1, int n=2) {
    recursion(ListNode p=2, int n=2) {
    	recursion(ListNode p=3, int n=2) {
    		recursion(ListNode p=4, int n=2) {
    			recursion(ListNode p=5, int n=2) {
    				recursion(ListNode p=null, int n=2) {
    					return 0; // 最内层序号0
					}
                    return 1; // 上一次返回值+1
				}
                return 2;
			}
            if(返回值 == n == 2) {
                // 删除 next
            }
            return 3;
		}
        return 4;
	}
    return 5;
}

但上述代码有一个问题,就是若删除的是第一个节点,它没有上一个节点,因此可以加一个哨兵来解决。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode sentinel = new ListNode(-1, head);
        recursion(sentinel, n);
        return sentinel.next;
    }

    /**
     * @param p 当前节点
     * @param n 需要删除倒数第 n 个节点
     * @return 当前节点为 倒数第几个节点
     */
    private int recursion(ListNode p, int n) {
        // 如果无节点了,就返回 0
        if (p == null) {
            return 0;
        }
        // nth 代表的是下一个节点的倒数位置
        int nth = recursion(p.next, n);
        // 如果下一个节点是 第 n 个节点,就需要删除下一个节点
        if (nth == n) {
            p.next = p.next.next;
        }
        // 当前节点的倒数位置 nth + 1
        return nth + 1;

    }
}

Question:p.next.next 不怕空指针吗?

Answer:

  • p 是待删除节点的上一个节点,如果能递归回到 p,那么 p.next 肯定有值,不会是 null
  • 且题目说明了 n >=1,不会因为 nth == 0 而让 p.next 指向最后的 null

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/20327.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

lol由于找不到vcruntine140_1.dll文件,vcruntime140_1.dll修复方法

家人们有没有遇到过打开游戏或者软件提示由于找不到vcruntime140_1.dll,无法继续执行此代码的情况,是不是不知道怎么修复呢?Vcruntime140_1.dll是一个Windows系统文件,它是Microsoft Visual C Redistributable for Visual Studio …

【嵌入式环境下linux内核及驱动学习笔记-(11-设备树)】

目录 1、设备树体系1.1 DTS /DTSI / DTC / DTB 2、基础语法2.1 节点语法2.1.1 通用名称建议 2.2 属性语法2.2.1 属性值 2.3 关于label2.4 节点的[unit-address] 与reg属性2.5 根节点 /2.6 标准属性compatible2.6.1 of_machine_is_compatible函数 2.7 地址编码2.7.1 标准属性#ad…

RabbitMQ养成记 (3.MQ的简单工作模式 和 Pub/sub 订阅模式)

上一篇是一个简单的helloworld。 我们直接发直接收 这种是最简单的。 下面我们再来接触更加复杂一点: 简单工作模式 work queues 工作队列模式: 这里注意 这里的消息 对两个消费者 c1 c2来说是竞争关系 而不是等份分发关系, 就像两个线程…

JVM 方法区

栈、堆、方法区的交互关系 线程共享角度: 新建对象分配: 方法区的理解 方法区(Method Area) 与 Java 堆一样,是各个线程共享的内存区域方法区在 JVM 启动的时候被创建,并且它的实际物理内存空间中和 Java 堆区一样都可以不连续的方法区的大小&#xf…

HNU-操作系统OS-实验Lab5

OS_Lab5_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 实验目的 了解第一个用户进程创建过程了解系统调用框架的实现机制了解ucore如何实现系统调用sys_fork/sys_exec/sys_exit/sys_wait来进行进程管理 实验…

1099 Build A Binary Search Tree(超详细注解+38行代码)

分数 30 全屏浏览题目 作者 CHEN, Yue 单位 浙江大学 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than the nodes key.The right subtree…

使用云服务器可以做什么?十大使用场景举例说明

使用阿里云服务器可以做什么?阿里云百科分享使用阿里云服务器常用的十大使用场景,说是十大场景实际上用途有很多,阿里云百科分享常见的云服务器使用场景,如本地搭建ChatGPT、个人网站或博客、运维测试、学习Linux、跑Python、小程…

详解c++STL—string组件

目录 一、string基本概念 1、本质 2、string和char * 区别: 3、特点: 二、string构造函数 1、构造函数原型 2、示例 三、string赋值操作 1、赋值的函数原型 2、示例 四、string字符串拼接 1、函数原型 2、示例 五、string查找和替换 1、功…

2023系统分析师---软件工程、系统规划高频错题

系统规划---成本效益分析 评价信息系统经济效益常用的方法主要有成本效益分析法,投入产出分析法和价值工程方法。盈亏平衡法常用于销售定价; 可行性分析 系统规划是信息系统生命周期的第一个阶段,其任务是对企业的环境、目标以及现有系统的状况进行初步调查,根据企业目标…

【利用AI让知识体系化】万字深入浅出Nginx

思维导图 文章目录 思维导图 第一部分:入门篇1.1 起步下载和安装Nginx启动NginxNginx配置文件Nginx命令行总结 1.2 Nginx的基本架构1.3 安装和配置Nginx1.4 Nginx的基本操作 第二部分:核心篇2.1 Nginx的请求处理2.2 Nginx的缓存机制2.3 Nginx的负载均衡机…

题解校验码—CRC循环校验码与海明校验码

码距 一个编码系统的码距是任意两个码字的最小距离。 例如个编码系统采用三位长度的二进制编码,若该系统有四种编码分别为:000,011,100,111,此编码系统中000与111的码距为3;011与000的码距为2…

Hard Patches Mining for Masked Image Modeling

摘要 蒙面图像建模(MIM)因其在学习可伸缩视觉表示方面的潜力而引起了广泛的研究关注。在典型的方法中,模型通常侧重于预测掩码补丁的特定内容,并且它们的性能与预定义的掩码策略高度相关。直观地说,这个过程可以被看作…

WiFi(Wireless Fidelity)基础(九)

目录 一、基本介绍(Introduction) 二、进化发展(Evolution) 三、PHY帧((PHY Frame ) 四、MAC帧(MAC Frame ) 五、协议(Protocol) 六、安全&#x…

【GAMES101】作业2学习总结

本系列博客为记录笔者在学习GAMES101课程时遇到的问题与思考。 GAMES101:课程官网GAMES101:B站视频GAMES101:相关文件下载(百度网盘) 一、基础题 本次作业的目的是为了让我们熟悉三角形栅格化的相关操作,通过Assignment2.pdf可以…

白嫖chatgpt的Edge插件,很难不爱啊

目录 🍁1.常见的Edge浏览器界面 🍁二.安装WebTab插件 🍁三.WebTab插件的各种功能 🍁1.支持免费的chatgpt,不限次数​编辑 🍁2.有几个休闲的小游戏可以玩耍,点击即玩。 🍁3.支…

618前夕,淘宝天猫大变革,探索电商天花板之上的价值

2023年淘宝天猫618商家大会,恰逢淘宝20周年,也是阿里“16N”组织架构改革,淘宝天猫“独立”经营后,管理和运营团队的首次亮相。除了淘宝天猫618的具体策略,最受关注的,还有淘宝天猫的大变革——涉及淘宝天猫…

AD9680+JESD204B接口+FPGA FMC高速率数据采集板卡

板卡概述: 【FMC_XM155】 FMC_XM155 是一款基于 VITA57.1 标准的,实现 2 路 14-bit、500MSPS/1GSPS/1.25GSPS 直流耦合 ADC 同步采集 FMC 子卡模 块。 该模块遵循 VITA57.1 规范,可直接与 FPGA 载卡配合使用,板 卡 ADC 器件采用…

CN学术期刊《西部素质教育》简介及投稿邮箱

《西部素质教育》(半月刊)创刊于2015年,是由青海人民出版社有限责任公司主管/主办的教育类学术期刊,本刊恪守“追踪教育研究前沿,关注教育实践热点,探索创新教育理念,传播教育教学信息&#xff…

Linux相关问题

中英文切换 super空格切换中英文;super指键盘上的Win键; 开机自启动服务设置 可视化方式:输入setup命令进入自启动服务配置;通过上下键选中服务,通过空格选择是否自启动该服务; 开启不同的终端 CTRLALT…

audioop.rms函数解读和代码例子

该audioop模块包含对声音片段的一些有用操作。它对由8,16或32位宽的有符号整数样本组成的声音片段进行操作,并以Python字符串存储。这与al和sunaudiodev模块使用的格式相同。所有标量项都是整数,除非另有规定。 audioop.rms 即 sqrt(sum(S_i^2)/n) 这个公…