news 2026/8/21 22:14:51

C++删除链表的倒数第 N 个结点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++删除链表的倒数第 N 个结点

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

代码逻辑逐行解释

采用快慢指针+虚拟头结点的标准解法,能正确实现“删除链表倒数第N个结点”的功能,下面逐行拆解核心逻辑:

一、链表节点定义
struct ListNode {
int val; // 节点存储的数值
ListNode *next; // 指向下一个节点的指针
// 无参构造函数:值为0,next为空
ListNode() : val(0), next(nullptr) {}
// 单参构造函数:指定值,next为空
ListNode(int x) : val(x), next(nullptr) {}
// 双参构造函数:指定值和下一个节点
ListNode(int x, ListNode *next) : val(x), next(next) {}
};

这是LeetCode中单向链表节点的标准定义,通过构造函数快速初始化节点。

二、核心解题函数

1. 创建虚拟头结点

ListNode* dummy = new ListNode(0, head);


作用:统一处理删除原头结点的边界情况。比如链表只有1个节点且要删除它时,若没有虚拟头结点,直接操作 head 会出现空指针问题;有了 dummy ,只需修改 dummy->next 即可。
细节: dummy 的值设为0(无实际意义), next 指向原链表的头结点 head 。

2. 初始化快慢指针

ListNode* fast = dummy; // 快指针 ListNode* slow = dummy; // 慢指针

快慢指针都从虚拟头结点 dummy 开始,目的是通过制造指针间隔,一次遍历找到目标节点的前驱。

3. 快指针先走n步

for(int i=0; i<n; i++){ fast = fast->next; }

作用:让快指针 fast 和慢指针 slow 之间形成n个节点的间隔。比如n=2时, fast 会比 slow 超前2个节点。
举例:若链表是 [1,2,3,4,5] 、n=2,这一步后 fast 会指向节点 2 , slow 仍指向 dummy 。

4. 快慢指针同步移动

while(fast->next != nullptr){ fast = fast->next; slow = slow->next; }

终止条件: fast->next == nullptr (快指针走到最后一个有效节点)。
作用:当快指针走到链表末尾时,慢指针会恰好停在倒数第n个节点的前驱节点。
举例:还是 [1,2,3,4,5] 、n=2的情况,这一步结束后:
fast 指向最后一个节点 5 ( fast->next 为 nullptr );
slow 指向节点 3 (倒数第2个节点 4 的前驱)。

5. 删除目标节点

slow->next = slow->next->next;

逻辑: slow->next 原本指向倒数第n个节点,将其改为指向该节点的下一个节点,就跳过了目标节点,实现“删除”(链表中删除节点的本质是断开引用)。
举例: slow 指向 3 时, slow->next 是 4 ,执行后 slow->next 变为 5 ,节点 4 被删除。

6. 释放内存并返回结果

ListNode* newHead = dummy->next; // 新链表的头结点是dummy的下一个节点 delete dummy; // 释放虚拟头结点的内存(避免内存泄漏) return newHead; // 返回删除节点后的链表头

细节: dummy->next 是新链表的真正头结点(若原头结点被删除, dummy->next 会指向原第二个节点;若未删除,仍指向原头结点);最后要释放 dummy ,否则会造成内存泄漏。

三、核心逻辑总结

1. 虚拟头结点:解决删除头结点的边界问题;
2. 快指针先走n步:制造n个节点的间隔;
3. 快慢指针同步移动:找到倒数第n个节点的前驱;
4. 修改指针引用:删除目标节点;
5. 释放内存并返回:完成最终操作。

该解法的时间复杂度为O(L)(L是链表长度,仅一次遍历),空间复杂度为O(1)(仅使用常数个指针),是这道题的最优解法。

“删除链表的倒数第N个结点”的最优解是快慢指针+虚拟头结点:通过创建虚拟头结点 dummy 统一处理删除原头结点的边界问题,先让快指针从 dummy 出发走 n 步,再让快慢指针同步移动至快指针抵达链表最后一个有效节点,此时慢指针恰好指向倒数第N个节点的前驱,通过修改慢指针的 next 引用即可删除目标节点,最后释放 dummy 并返回其 next 作为新链表头;该解法仅需一次线性遍历,时间复杂度为O(L)(L为链表长度),空间复杂度为O(1),同时需注意循环条件的准确性(快指针走 n 步、同步移动终止于 fast->next=nullptr )和C++中的内存释放,避免越界与内存泄漏问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/20 2:10:40

铜及铜合金的特性、应用与检测

铜及铜合金的特性铜及铜合金是一种以纯铜为基础&#xff0c;添加其他元素形成的合金材料。纯铜本身具有独特的紫红色外观&#xff0c;而铜合金则会因添加的元素种类和比例不同&#xff0c;呈现出不同的性能和外观特征。1.物理性质铜的导电和导热性能极为出色&#xff0c;其电导…

作者头像 李华
网站建设 2026/8/20 9:39:12

Python 爬虫实战:Scrapy 管道(Pipeline)数据持久化

前言 Scrapy 框架中&#xff0c;爬虫解析出的 Item 数据最终需落地存储&#xff0c;而管道&#xff08;Pipeline&#xff09;是实现数据持久化的核心组件。相较于直接在爬虫文件中处理数据存储&#xff0c;Pipeline 具备模块化、可扩展、支持多管道协同处理的优势&#xff0c;…

作者头像 李华
网站建设 2026/8/20 19:26:23

水库水电站泄洪预警广播解决方案

一、方案背景 水库水电站泄洪是保障大坝安全和流域防洪的重要调控手段&#xff0c;但泄洪过程中可能对下游河道沿岸居民生命财产安全构成威胁。本解决方案旨在通过构建一套集实时监测、智能预警、精准广播于一体的综合性系统&#xff0c;实现泄洪信息的快速感知、智能研判和高效…

作者头像 李华
网站建设 2026/8/21 7:46:13

Python 爬虫实战:Selenium 切换标签页与窗口

前言 在复杂的爬虫场景中&#xff08;如多页面交互、弹窗处理、新窗口打开的内容爬取&#xff09;&#xff0c;Selenium 对标签页 / 窗口的精准控制是核心能力之一。很多动态网站会通过 “新标签页打开详情页”“弹窗窗口展示关键数据” 等方式呈现内容&#xff0c;若无法实现…

作者头像 李华
网站建设 2026/8/21 6:19:10

PPT模板瘦身方法!!!

你是否疑惑使用自己大学的ppt模板做汇报&#xff0c;好看是好看&#xff0c;但是怎么做完之后大小突破天际&#xff01;&#xff01;ppt还没编辑就有40M&#xff08;可能不止&#xff09;打底&#xff0c;做完之后直接60M了&#xff0c;想传给同组队员修改或者传给老师&#xf…

作者头像 李华
网站建设 2026/8/21 6:20:22

STM32F103基于CAN协议的bootload程序源码,成功量产应用于实际项目

基于STM32F103的CAN bootload程序源码&#xff0c;包含boot和app两个工程&#xff0c;已应用到实际项目并量产最近在量产一款工业控制器时遇到了头疼的问题——产品装到现场后发现程序有bug咋升级&#xff1f;总不能每次都拆下来用ST-Link烧录吧&#xff1f;这时候CAN总线Bootl…

作者头像 李华