力扣题目解析--删除链表的倒数第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 <= 300 <= Node.val <= 1001 <= n <= sz
代码展示
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode *dummy=new ListNode(0);dummy->next=head;ListNode *current=dummy;ListNode *fast=dummy;ListNode *slow=dummy;for(int i=0;i<n;i++){if(fast->next==nullptr){delete dummy;return head;}fast=fast->next;}while (fast->next!=nullptr){fast=fast->next;slow=slow->next;}ListNode* toDelete =slow->next;slow->next=slow->next->next;delete toDelete;ListNode* newHead=dummy->next;delete dummy;return newHead;}
};
写者心得
要想搞明白这个题就必须得先看得懂题目在开头给的注释,那里面有关于对于列表是怎么设置的,写者就是在先去搞明白他是怎样设置列表之后再写代码的。这结构体设置的并不难,但其中有一个点是我搞错了的,val它其实是链表中的值,而我一直把它当做链表的一个元素来看待,所以造成了一些错误。代码有一些写的比较好的地方:
1.虚拟头节点
对比分析
-
删除头节点:
- 没有虚拟头节点:需要单独处理头节点的删除情况,代码复杂度增加。
- 有虚拟头节点:删除头节点和其他节点的操作一致,代码简洁。
-
代码简洁性:
- 没有虚拟头节点:需要更多的条件判断,代码冗长。
- 有虚拟头节点:代码结构更清晰,易于理解和维护。
虚拟头节点在链表中是非常常用的,其实它的作用很简单,就是当你在处理列表中节点的时候,有可能会处理到头节点的情况,正是因为我们把这个头节点虚拟化了,所以就不需要考虑这个问题了,这样子可以省去我们许多关于头节点的条件设置
2.双指针
但其实这个双指针和我们在前面所用到的双指针是完全不同的两个东西,过去的双指针是为了遍历数组 ,而这个双指针则是为了寻找节点,其实这个思路很像是双循环,一个负责遍历,另一个则负责删除,所以一个指针设为快指针,另一个指针设为慢指针,这样就可以在链表之中寻找节点,我想这个方法应该和双循环暴力破解有异曲同工之处,而在接下来我们处理链表问题的时候,会经常用到这样子的思路和这样的做法。
代码解析
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
这部分定义了一个单链表节点的结构体 ListNode,包含三个构造函数:
- 默认构造函数:
ListNode() : val(0), next(nullptr) {} - 带一个参数的构造函数:
ListNode(int x) : val(x), next(nullptr) {} - 带两个参数的构造函数:
ListNode(int x, ListNode *next) : val(x), next(next) {}
创建虚拟头节点
ListNode *dummy = new ListNode(0);dummy->next = head;
- 创建一个虚拟头节点
dummy,其值为0,next指向原链表的头节点head。 - 虚拟头节点的作用是简化边界条件的处理,特别是删除头节点的情况。
初始化指针
ListNode *current = dummy;ListNode *fast = dummy;ListNode *slow = dummy;
- 初始化三个指针
current、fast和slow,都指向虚拟头节点dummy。
快指针先走 n 步
for (int i = 0; i < n; i++) {if (fast->next == nullptr) {delete dummy;return head;}fast = fast->next;}
- 使用一个
for循环让快指针fast先向前移动 nn 步。 - 在每次移动前,检查
fast->next是否为nullptr,如果是,说明链表长度小于 nn,直接返回原链表。 - 如果链表长度大于等于 nn,继续移动快指针。
同步移动快指针和慢指针
while (fast->next != nullptr) {fast = fast->next;slow = slow->next;}
- 使用一个
while循环同步移动快指针fast和慢指针slow,直到快指针到达链表的末尾。 - 当快指针到达链表末尾时,慢指针正好指向倒数第 nn 个节点的前一个节点。
删除慢指针的下一个节点
ListNode* toDelete = slow->next;slow->next = slow->next->next;delete toDelete;
- 记录要删除的节点
toDelete,即slow->next。 - 将慢指针的
next指针指向要删除节点的下一个节点,从而跳过要删除的节点。 - 释放要删除节点的内存。
返回新的头节点
ListNode* newHead = dummy->next;delete dummy;return newHead;}
};
- 返回新的头节点
newHead,即dummy->next。 - 释放虚拟头节点的内存。
- 返回新的头节点。
总结
通过使用虚拟头节点和双指针法,我们可以有效地删除链表中的倒数第 nn 个节点。虚拟头节点简化了边界条件的处理,双指针法确保了我们能够准确地找到要删除的节点的位置。
相关文章:
力扣题目解析--删除链表的倒数第n个节点
题目 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出:[]示例 3&…...
Knowledge Graph-Enhanced Large Language Models via Path Selection
研究背景 研究问题:这篇文章要解决的问题是大型语言模型(LLMs)在生成输出时存在的事实不准确性,即所谓的幻觉问题。尽管LLMs在各种实际应用中表现出色,但当遇到超出训练语料库范围的新知识时,它们通常会生…...
Android 项目模型配置管理
Android 项目配置管理 项目模型相关的配置管理config.gradle文件:build.gradle文件: 参考地址 项目模型相关的配置管理 以下是一个完整的build.gradle和config.gradle示例: config.gradle文件: ext {// 模型相关配置࿰…...
「QT」几何数据类 之 QSizeF 浮点型尺寸类
✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…...
Essential Cell Biology--Fifth Edition--Chapter one(2)
1.1.1.3 Living Cells Are Self-Replicating Collections of Catalysts 催化剂集合 生物最常被引用的特性之一是它们的繁殖能力。对于细胞来说,这个过程包括复制它们的遗传物质和其他成分,然后分裂成两个,产生一对子细胞[daughter cells]&a…...
大语言模型LLMs在医学领域的最新进展总结
我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 相比其他学科,医学AI,是发表学术成果最多的领域。 医学数据的多样性和复杂性(包括文本、图像、基因组数据等),使得…...
云防护单节点2T抗攻击能力意味着什么?
随着互联网的发展,DDoS攻击的规模和频率不断增加,对企业和个人用户的网络服务造成了严重威胁。云防护服务作为一种高效的DDoS防护手段,逐渐成为许多企业的首选。本文将重点讨论云防护单节点2T(太比特每秒)抗攻击能力的…...
IDEA在编译时: java: 找不到符号符号: 变量 log
一、问题 IDEA在编译的时候报Error:(30, 17) java: 找不到符号符号: 变量 log Error:(30, 17) java: 找不到符号 符号: 变量 log 位置: 类 com.mokerson.rabbitmq.config.RabbitMqConfig 二、解决方案 背景:下载其他同事代码时,第一次运行,…...
HTML 基础架构:理解网页的骨架
HTML的文档结构主要由以下几个部分组成:<html>、<head>和<body>。 <html>标签是HTML文档的根元素,用来包裹整个HTML文档的内容。<head>标签用于定义文档的头部,包含了一些元数据和其他不直接显示在页面上的内…...
FPGA学习笔记#5 Vitis HLS For循环的优化(1)
本笔记使用的Vitis HLS版本为2022.2,在windows11下运行,仿真part为xcku15p_CIV-ffva1156-2LV-e,主要根据教程:跟Xilinx SAE 学HLS系列视频讲座-高亚军进行学习 从这一篇开始正式进入HLS对C代码的优化笔记 目录 1.循环优化中的基…...
web实操4——servlet体系结构
servlet体系结构 我们基本都只实现service方法,其余几个都不用, 之前我们直接实现servlet接口,所有的方法都必须实现,不用也得写,不然报错,写了又不用当摆设。 能不能只要定义一个service方法就可以&…...
Linux开发讲课48--- Linux 文件系统概览
本文旨在高屋建瓴地来讨论 Linux 文件系统概念,而不是对某种特定的文件系统,比如 EXT4 是如何工作的进行具体的描述。另外,本文也不是一个文件系统命令的教程。 每台通用计算机都需要将各种数据存储在硬盘驱动器(HDD)…...
Node.js 模块详解
模块的概念 Node.js 运行在 V8 JavaScript 引擎上,通过 require() 函数导入相关模块来处理服务器端的各种进程。一个 Node.js 模块可以是一个函数库、类集合或其他可重用的代码,通常存储在一个或多个 .js 文件中。 例如,启动一个 Node.js 服…...
大厂面试真题-说说tomcat的优缺点
Tomcat作为服务器,特别是作为Java Web服务器,具有一系列优点和缺点。以下是对其优缺点的详细分析: 优点 开源免费: Tomcat是一个免费、开源的Web服务器,用户可以在任何环境下自由使用,无需支付任何费用。…...
Linux系统编译boot后发现编译时间与Windows系统不一致的解决方案
现象 如下图,从filezilla软件看虚拟机Linux中编译的uboot.img修改时间与Windows系统时间不同 解决过程 在Linux中查看编译的uboot详细信息,从而得到编译时间。终端输入ls -l后,如下图: 结论 说明在Linux是按照Windows系统时…...
WPS Office手机去广高级版
工具介绍功能特点 WPS Office是使用人数最多的移动办公软件,独有手机阅读模式,字体清晰翻页流畅;完美支持文字,表格,演示,PDF等51种文档格式;新版本具有海量精美模版及高级功能 安装环境 [名称…...
Python爬虫基础-正则表达式!
前言 正则表达式是对字符串的一种逻辑公式,用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则的字符串”,此字符串用来表示对字符串的一种“过滤”逻辑。正在在很多开发语言中都存在,而非python独有。对其知识点…...
Python处理PDF组件使用及注意事项
在 Python 中处理 PDF 文件时, 使用的组件及注意事项如下: 1. PyPDF2 / PyPDF4 说明: PyPDF2 和 PyPDF4 都是功能强大的 PDF 操作库,适用于合并、拆分、旋转 PDF 文件,提取 PDF 元数据等。PyPDF4 是 PyPDF2 的一个分…...
langgraph_plan_and_execute
整体入门demo 教程概览 欢迎来到LangGraph教程! 这些笔记本通过构建各种语言代理和应用程序,介绍了如何使用LangGraph。 快速入门(Quick Start) 快速入门部分通过一个全面的入门教程,帮助您从零开始构建一个代理&a…...
[代码随想录打卡Day8] 344.反转字符串 541. 反转字符串II 54. 替换数字
反转字符串 难度:易。 问题描述:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 这个就是开头…...
AWE Designer生成的awb文件到底是什么?一份给嵌入式音频开发者的二进制文件解析与烧录避坑指南
AWB文件深度解析:嵌入式音频开发者的二进制文件操作指南 在嵌入式音频开发领域,AWE Designer工具链生成的AWB文件常常让开发者感到神秘又困惑。这个看似普通的二进制文件,实际上承载着音频算法实现的核心逻辑。许多开发者在烧录AWB文件到Flas…...
Nooploop TOFSense激光测距模块:从快速上手指南到多平台实战应用
1. Nooploop TOFSense激光测距模块初体验 第一次拿到TOFSense激光测距模块时,我完全被它的小巧体积震惊了。这个比火柴盒大不了多少的装置,居然能实现0.1-12米的精确测距,精度高达1cm!作为一名经常在无人机项目中折腾的嵌入式工程…...
用Python+OpenCV搞定热红外与可见光图像自动对齐(附完整代码与避坑指南)
PythonOpenCV实战:热红外与可见光图像自动配准全流程解析 引言 在工业检测、安防监控、医疗诊断等领域,热红外与可见光图像的融合分析正成为关键技术。两种成像模式各具优势:可见光图像色彩丰富、细节清晰,而热红外图像则能揭示物…...
如何高效绘制专业电路图:Draw.io电子工程库完全指南
如何高效绘制专业电路图:Draw.io电子工程库完全指南 【免费下载链接】Draw-io-ECE Custom-made draw.io-shapes - in the form of an importable library - for drawing circuits and conceptual drawings in draw.io. 项目地址: https://gitcode.com/gh_mirrors/…...
第14章:C++ 代码规范评审
第14章:C++ 代码规范评审 本章定位:第四卷《实战卷》第四篇"工程化与编译链接"第 14 章。 与第 13 章《静态分析工具》构成"机器查 + 人查"互补:能机器查的让 lint 拦,必须人脑判断的进 review。 目录 01.规范与评审定位 1.1 规范的三个层级 1.2 评审解…...
低空经济公司官网与宣传材料常见的5个问题:为什么看起来先进却不够可信
在B2B企业的品牌升级和内容分发中,“低空经济公司官网与宣传材料常见的5个问题:为什么看起来先进却不够可信”不是一个单点问题,而是关系到客户理解效率、销售推进效率和品牌长期信任感的系统问题。低空经济企业在表达上最容易走向一个误区&a…...
不使用void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* tim_encoderHandle)增强代码的层级结构注意事项
这是正常用cube Max生成的代码,这里以设置编码器为例。 GPIO初始化函数放在HAL_TIM_Encoder_MspInit这个回调函数中。代码正常运行/* TIM3 init function */ void MX_TIM3_Init(void) {TIM_Encoder_InitTypeDef sConfig {0};TIM_MasterConfigTypeDef sMasterConfig…...
ROS小车转弯卡顿?手把手教你用Python搞定cmd_vel到阿克曼模型的平滑转换
ROS小车转弯卡顿?Python实现cmd_vel到阿克曼模型的平滑转换实战 当你在Gazebo仿真或实际运行ROS控制的阿克曼转向小车时,是否遇到过车体转弯时"一耸一耸"、运动不连贯的尴尬情况?这种卡顿现象往往源于cmd_vel指令到阿克曼运动模型转…...
手机上的Linux:用Termux 0.118.0打造Python 3.10.4爬虫环境,实测下载‘拷贝漫画’全流程
在安卓手机上构建Python爬虫环境:Termux实战指南 你是否遇到过这样的场景:在地铁上突然想到一个绝妙的爬虫点子,但手边只有一部手机?或者想在平板上直接下载漫画却苦于没有合适的工具?Termux正是解决这些痛点的神器。这…...
9.9元ESP32-C3移植RT-Thread Nano:低成本RTOS开发与调试实战
1. 项目概述:当开源RTOS遇上性价比神板最近在捣鼓嵌入式开发,发现了一块宝藏开发板——ESP32-C3的某个简约款,价格直接干到了9.9元。这个价格,别说喝杯奶茶了,连个像样的模块都买不到,但它不仅能跑起来&…...
