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

文章目录

  • 19. 删除链表的倒数第 N 个结点
    • 题目描述
    • 将删除倒数第n个节点转化为删除第n个节点
    • 双指针

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

题目描述

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

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

提示:

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

将删除倒数第n个节点转化为删除第n个节点

  先用一个哑节点(虚拟头节点)来简化删除头节点的情况。然后,它通过第一次遍历计算出链表的长度,接着计算出要到达的节点,最后通过第二次遍历找到目标节点的前一个节点。通过修改指针,实现了目标节点的删除,并且在结束前释放了删除节点和哑节点占用的内存。最终返回了新链表的头节点。
  删除第n个节点时需要找到前一个节点才能删除
在这里插入图片描述

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyhead = new ListNode(0); // 创建一个哑节点,其值为0,next指向链表的头节点head
        dummyhead->next = head;
        ListNode* cur = dummyhead; // 创建一个指针cur,初始化为指向哑节点
        int size = 0;
        while(cur) { // 遍历整个链表来计算链表的长度
            cur = cur->next;
            size++;
        }
        cur = dummyhead; // 重置cur指针回到哑节点的位置,准备第二次遍历
        int a = size - n - 1; // 计算正向第size-n个节点的索引(因为哑节点的存在,所以要额外减1)

        while(a--) { // 移动cur指针到正向第size-n个节点的前一个节点上
            cur = cur->next;
        }
        ListNode* tmp = cur->next; // 创建一个临时指针tmp,指向要删除的节点
        cur->next = cur->next->next; // 将要删除节点的前一个节点的next指向要删除节点的下一个节点,从而断开连接

        delete tmp; // 删除tmp指针指向的节点,释放内存

        ListNode* newHead = dummyhead->next; // 保存新的头节点,即哑节点的下一个节点
        delete dummyhead; // 删除哑节点,释放内存
        
        return newHead; // 返回新的头节点
    }
};

双指针

  通过使用两个指针来实现的,一个快指针(fast)首先向前移动 n 步,然后快指针和慢指针(slow)一起移动直到快指针到达链表尾部。此时慢指针指向的是倒数第 n 个节点的前一个节点。然后该节点被删除,并释放其内存。最后,函数删除了在开始时创建的哑节点(虚拟头节点),并返回链表的新头节点。

  • fast先移动n步
    在这里插入图片描述
  • 然后fast和slow再同时移动,fast移动到NULL,slow随着fast一起移动就能找到需要删除的节点,因为删除节点需要找到删除节点的前一个结点,所以fast只需要移动到NULL的前一个结点,slow结点也就移动到删除节点的前一个结点
    在这里插入图片描述
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 创建一个哑节点(dummy head),其值不重要,目的是为了简化边缘情况的处理,
        // 比如删除的是链表的头节点。哑节点的下一个节点是链表的实际头节点。
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;

        // 创建两个指针,fast 和 slow,都开始时指向哑节点
        ListNode* fast = dummyhead;
        ListNode* slow = dummyhead;

        // 移动快指针fast,使其领先慢指针slow n 个节点。
        // 这是为了当fast指针到达链表末尾时,slow指针将指向倒数第n个节点的前一个节点。
        while(n--)
            fast = fast->next;

        // 同时移动快指针和慢指针,直到快指针到达最后一个节点。
        // 这样做是为了找到倒数第n个节点,因为当快指针到达链表尾部时,
        // 慢指针将会指向倒数第n个节点前的一个节点。
        while(fast->next != nullptr) {
            fast = fast->next;
            slow = slow->next;
        }

        // slow指针现在指向倒数第n个节点的前一个节点,
        // tmp是倒数第n个节点,准备删除这个节点。
        ListNode* tmp = slow->next;

        // 断开倒数第n个节点的连接,将其前一个节点的next指向其下一个节点,
        // 从而将其从链表中移除。
        slow->next = slow->next->next;

        // 删除tmp指针指向的节点,即释放倒数第n个节点的内存。
        delete tmp;
        // 将tmp设置为nullptr,防止悬挂指针导致的未定义行为。
        tmp = nullptr;

        // newhead是指向链表新头节点的指针,即哑节点之后的节点。
        ListNode* newhead = dummyhead->next;

        // 删除哑节点,释放其内存。
        delete dummyhead;
        // 将dummyhead设置为nullptr,防止悬挂指针导致的未定义行为。
        dummyhead = nullptr;

        // 返回链表的新头节点。
        return newhead;
    }
};

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

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

相关文章

(28)Linux 信号保存 信号处理 不可重入函数

首先介绍几个新的概念&#xff1a; 信号递达(Delivery)&#xff1a;实际执行信号的处理动作。信号未决(Pending)&#xff1a;信号从产生到递达之间的状态。信号阻塞(Block)&#xff1a;被阻塞的信号产生时将保持在未决状态&#xff0c;直达解除对该信号的阻塞&#xff0c;才执…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之CheckboxGroup组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之CheckboxGroup组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、CheckboxGroup组件 提供多选框组件&#xff0c;通常用于某选项的打开或关…

【Vue实用功能】Vue实现文档在线预览功能,在线预览PDF、Word等office文件

1、Office Web(微软的开发接口) 优点 没有 Office也可以直接查看Office 文件适用于移动端、PC无需下载文件就可以在浏览器中查看 <iframe src"文档地址" frameborder"0" /> const docUrl 外网可预览的地址 const url encodeURIComponent(docUrl…

python零散学习

__name__和__main__关系 python函数入口 每个模块都有一个 __name__ 属性&#xff0c;当其值是 __main__ 时&#xff0c;表明该模块自身在运行&#xff08;此时__name____main__&#xff09;&#xff0c;否则是被引入&#xff08;此时__name__自身的模块名称&#xff09;。 变…

深度强化学习(王树森)笔记06

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…

SpringBoot整合Quartz任务,java对任务创建、删除、修改、查询

SpringBoot整合Quartz定时任务 1、定时任务相关概念2、SpringBoot集成Quartz2.1、Quartz相关表2.2、pom.xml2.3、application.yml2.4、java对任务增删改查2.4.1、common相关配置类2.4.2、pojo类2.4.3、task类2.4.4、Controller类 3、一些理解3.1、Quartz的集群原理以及配置&…

Android 基础技术——Bitmap

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 Bitmap Bitmap 内存如何计算 占用内存 宽 * 缩放比例 * 高 * 缩放比例 * 每个像素所占字节 缩放比例 设备dpi/图片所在目录的dpi Bitmap加载优化&#xff1f;不改变图片质量的情况下怎么优化&am…

AlmaLinux上安装Docker

AlmaLinux上安装Docker 文章目录 AlmaLinux上安装Docker一、前言二、具体步骤1、Docker 下载更新系统包索引&#xff1a;添加Docker仓库&#xff1a;安装Docker引擎&#xff1a; 2、Docker服务启动启动Docker服务&#xff1a;设置Docker开机自启&#xff1a; 3、Docker 安装验证…

基于SSM的网络办公系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的网络办公系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

mysql注入联合查询

环境搭建 下载复现漏洞的包 下载小皮面板 将下载好的文件解压在小皮面板的phpstudy_pro\WWW路径下 将这个文件phpstudy_pro\WWW\sqli-labs-php7-master\sql-connections\db-creds.inc 中的密码更改为小皮面板中的密码 选择php版本 在小皮中启动nginx和数据库 使用环回地址访…

java如何处理多线程异常

一、一个线程在执行过程中发生了异常会怎样&#xff1f; 那要看我们是否对这个异常进行了处理&#xff0c;如果处理了&#xff0c;那么线程会继续执行&#xff0c;如果没有处理&#xff0c;那么线程会释放掉自己所持有的锁&#xff0c;退出执行&#xff0c;如果这个线程是主线程…

linux 基于科大讯飞的文字转语音使用

官方文档地址&#xff1a;离线语音合成 Linux SDK 文档 | 讯飞开放平台文档中心 一、SDK下载 1、点击上面官方文档地址的链接&#xff0c;可以跳转到以下界面。 2、点击“普通版”&#xff0c;跳转到以下界面。 3、点击“下载”跳转到以下界面 4、最后&#xff0c;点击“SDK下…

电脑和手机连接酒店的wifi,网络不通导致charles无法抓手机的包

查看苹果手机&#xff0c;连wifi后的ip地址 电脑去ping 手机的ip地址&#xff0c;发现ping不通 解决方案&#xff1a; 应该是酒店wifi的问题&#xff0c;让朋友开个手机热点&#xff0c;电脑和我的手机都连这个热点&#xff0c;就可以抓包了

【vue2】路由之 Vue Router

文章目录 一、安装二、基础使用1、简单的示例2、动态路由2.1 定义动态路径参数2.2 获取动态路径的参数2.3 捕获所有路由 3、嵌套路由4、编程式的导航4.1 router.push4.2 router.replace4.3 router.go(n) 5、命名路由6、重定向 三、进阶1、导航守卫1.1 全局前置守卫1.2 全局后置…

日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

文章目录 使用 docker 在 heroku 上单独部署 vue 前端使用 docker 在 heroku 上单独部署 django 后端创建 heroku 项目构建 Dockerfile设置 settings.pydatabase静态文件管理安全设置applicaiton & 中间件配置 设置 requirements.txtheroku container 部署应用 前后端分别部…

SpringBoot整合Xxl-Job实现异步任务调度中心

目录 一、下载 1、源码 2、项目结构 3、模块说明 二、部署任务调度中心 1、创建数据库xxl-job 2、配置数据库 3、启动admin模块 4、打开任务调度中心 三、SpringBoot整合xxl-job 1、导入依赖 2、配置yml文件 3、配置类 4、启动项目 5、任务配置 6、测试 一、下…

Windows 和 Anolis 通过 Docker 安装 Milvus 2.3.4

Windows 10 通过 Docker 安装 Milvus 2.3.4 一.Windows 安装 Docker二.Milvus 下载1.下载2.安装1.Windows 下安装&#xff08;指定好Docker文件目录&#xff09;2.Anolis下安装 三.数据库访问1.ATTU 客户端下载 一.Windows 安装 Docker Docker 下载 双击安装即可&#xff0c;安…

[嵌入式系统-5]:龙芯1B 开发学习套件 -2- LoongIDE 集成开发环境集成开发环境的安装步骤

目录 一、LoongIDE&#xff08;龙芯开发工具集成环境&#xff09;概述 1.1 概述 二、软件开发环境的安装过程 2.0 注意事项 2.1 步骤1&#xff1a;MingW运行环境 2.2 步骤2&#xff1a;安装LoongIDE 2.3 步骤3&#xff1a;安装MIPS工具链 2.4 配置工具链 2.5 重启电脑…

总结NB-IoT模块和单片机的区别

在学习了NB-IoT模块后&#xff0c;紧接着又学习了单片机系统&#xff0c;单片机和NB-IoT模块有什么不同之处呢&#xff0c;总结为以下几点。 大纲如图&#xff1a; 一、硬件层面 1、采用芯片不同&#xff0c; &#xff08;1&#xff09;封装&#xff1a;封装尺寸、方式不同&a…

Qt应用软件【串口篇】串口通信

文章目录 1.串口概述2.串口传输数据的基本原理电信号的传输过程 3.串口的几个概念数据位&#xff08;Data Bits&#xff09;奇偶校验位&#xff08;Parity Bit&#xff09;停止位&#xff08;Stop Bits&#xff09;流控制&#xff08;Flow Control&#xff09;波特率&#xff0…
最新文章