news 2026/4/15 8:02:46

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/4/8 21:00:11

SGMICRO圣邦微 SGM2017-3.3XN5/TR SOT23-5 线性稳压器(LDO)

特性 工作输入电压范围:2.5V至5.5V 固定输出电压为2.8V和3.3V 输出电流:300mA 电流:77微A(TYR) 低压差:在300mA时为300mV(典型值)低噪声:30uVrms(典型值)(10Hz至100kHz)高PSRR:在1kHz时典型值为73dB 电流限制与热保护 使用小型封装陶瓷电容实现稳定运行关断供电电流:0.01uA(典型…

作者头像 李华
网站建设 2026/4/8 9:33:31

SGMICRO圣邦微 SGM2019-1.3YN5G/TR SOT-153 线性稳压器(LDO)

特性 工作输入电压范围:2.5V至5.5V 固定输出电压: 1.2V,1.5V,1.8V,2.5V,2.6V,2.8V,2.85V,3.0V,3.3V可调输出电压范围:1.2V至5.0V输出电压精度:25C时士2.5% 低输出噪声:30pVRMS(典型值) 低压差电压:在300mA时为270mV(典型值) 高PSRR:在1kHz时典型值为74dB 关断电流:0.01uA(典型值…

作者头像 李华
网站建设 2026/4/14 22:56:31

SGMICRO圣邦微 SGM2019-1.5YC5G/TR SC70-5 线性稳压器(LDO)

特性工作输入电压范围&#xff1a;2.5V至5.5V固定输出电压&#xff1a;1.2V、1.5V、1.8V、2.5V、2.6V、2.8V、2.85V、3.0V、3.3V可调输出电压范围&#xff1a;1.2V至5.0V输出电压精度&#xff1a;25C时为2.5%低输出噪声&#xff1a;30μV_RMS&#xff08;典型值&#xff09;低压…

作者头像 李华
网站建设 2026/4/8 6:06:38

Python 爬虫实战:User-Agent 随机切换防封禁

前言 在网络爬虫的开发与应用过程中&#xff0c;反爬机制是绕不开的核心问题。其中&#xff0c;基于请求头中 User-Agent 字段的校验是网站最基础也是最常用的反爬手段之一。固定的 User-Agent 会被服务器快速识别为爬虫程序&#xff0c;进而触发 IP 封禁、请求限制等反爬措施…

作者头像 李华
网站建设 2026/4/12 0:40:02

一、地理探测器:是什么?

Geo Detector是 用Excel编制的地理探测器软件, 可从以下网址免费下载:http://www.geodetector.org/。地理探测器方法简介地理探测器&#xff08;Geographical Detector&#xff09;是一种用于识别空间分异特征及其驱动因素的统计分析方法&#xff0c;最早由王劲峰等学者提出&am…

作者头像 李华