练习题 删除链表的倒数第N个结点

news2025/4/7 10:27:52
题目

给你一个链表,删除链表的倒数第 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
提交代码
提交代码1
//删除链表的倒数第N个结点

//链表->单向搜索
//两个指针一起走,指针1比指针2快一倍

#include<iostream>
using namespace std;

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 *head;//链表头
int n;//倒数第n个节点 

//双指针
void twoPointers(){
	int i = 0,j = 0;//统计两个指针走了多少步 
	//两个指针,p1走1步,p2走两步
	ListNode* p1 = head;
	ListNode* p2 = head;
	
	//移动两个指针 
	while(p2 != nullptr){
		p2 = p2->next;
		j++;
		
		if(p2 != nullptr){
			p2 = p2->next;
			j++;
			p1 = p1->next;
			i++;
		}
	}
	
	//求要删除的节点的位置
	int k = j - n;
	
	//判断要删除的位置在前后哪一段
	if(k <= i){
		//从头节点开始找
		ListNode *last = new ListNode();//记录上一个节点位置
		last->next = head; 
		ListNode *t = head;//遍历链表 
		for(int m = 0;m < k;m++){
			last = t;
			t = t->next;
		}
		last->next = t->next;
		//删除的是头结点的时候 
		if(t == head){
			head = last->next;
		} 
	}else{
		//从i节点开始找 
		ListNode *last;//记录上一个节点位置
		last = p1; 
		ListNode *t = p1->next;//遍历链表 
		i++;
		for(;i < k;i++){
			last = t;
			t = t->next;
		}
		last->next = t->next;
	}
} 

int main(){
	//输入整数数组  
	/*int t; 
	
	while(cin.peek() != '\n'){
		scanf("%d",&t);
		nums.push_back(t);
	}*/
	
	//输入链表
	head = new ListNode();
	ListNode* temp = head;
	int t;//存储节点值
	while(cin.peek() != '\n'){
		scanf("%d",&t);
		ListNode *next = new ListNode(t);
		temp->next = next;
		temp = next;
	}
	head = head->next;
	
	//输入要删除的倒数第几个节点
	scanf("%d",&n); 
	
	//-------------------------------
	
	//双指针
	twoPointers();
	
	//输出结果
	for(ListNode* t = head;t != nullptr;t = t->next){
		printf("%d ",t->val);
	}
	
	return 0;
} 

解题思路:链表具有搜索单向性,要删掉倒数第几个节点,可以遍历一遍链表,知道链表的节点总数,然后确定删除的节点的位置。可以辅助一个指针,指针2每次走两步,指针1每次走1步,指针2到终点时指针1在半程,计算出位置后,判断从头指针开始找删除节点方便还是从指针1开始找方便,从而节省时间。

提交代码2
//删除链表的倒数第N个结点

//链表->单向搜索
//两个指针一起走,指针1比指针2快一倍

#include<iostream>
using namespace std;

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 *head;//链表头
int n;//倒数第n个节点 

//双指针
/*void twoPointers(){
	int i = 0,j = 0;//统计两个指针走了多少步 
	//两个指针,p1走1步,p2走两步
	ListNode* p1 = head;
	ListNode* p2 = head;
	
	//移动两个指针 
	while(p2 != nullptr){
		p2 = p2->next;
		j++;
		
		if(p2 != nullptr){
			p2 = p2->next;
			j++;
			p1 = p1->next;
			i++;
		}
	}
	
	//求要删除的节点的位置
	int k = j - n;
	
	//判断要删除的位置在前后哪一段
	if(k <= i){
		//从头节点开始找
		ListNode *last = new ListNode();//记录上一个节点位置
		last->next = head; 
		ListNode *t = head;//遍历链表 
		for(int m = 0;m < k;m++){
			last = t;
			t = t->next;
		}
		last->next = t->next;
		//删除的是头结点的时候 
		if(t == head){
			head = last->next;
		} 
	}else{
		//从i节点开始找 
		ListNode *last;//记录上一个节点位置
		last = p1; 
		ListNode *t = p1->next;//遍历链表 
		i++;
		for(;i < k;i++){
			last = t;
			t = t->next;
		}
		last->next = t->next;
	}
} */
//优化后的双指针
//指针2比指针1先走n步,则指针2到终点时指针1就是要删除的节点 
void twoPointers(){
	ListNode* p1 = head;
	ListNode* p2 = head;
	ListNode* last = new ListNode();//指针1的上一个节点指针
	
	//指针2先走n步
	for(int i = 0;i < n;i++){
		p2 = p2->next;
	} 
	
	//两个指针一起走
	while(p2 != nullptr){
		last = p1;
		p1 = p1->next;
		p2 = p2->next;
	} 
	
	//删除指针1节点
	last->next = p1->next;
	
	//注意删除的是否是头结点
	if(p1 == head){
		head = last->next;
	} 
} 

int main(){
	//输入整数数组  
	/*int t; 
	
	while(cin.peek() != '\n'){
		scanf("%d",&t);
		nums.push_back(t);
	}*/
	
	//输入链表
	head = new ListNode();
	ListNode* temp = head;
	int t;//存储节点值
	while(cin.peek() != '\n'){
		scanf("%d",&t);
		ListNode *next = new ListNode(t);
		temp->next = next;
		temp = next;
	}
	head = head->next;
	
	//输入要删除的倒数第几个节点
	scanf("%d",&n); 
	
	//-------------------------------
	
	//双指针
	twoPointers();
	
	//输出结果
	for(ListNode* t = head;t != nullptr;t = t->next){
		printf("%d ",t->val);
	}
	
	return 0;
} 

 解题思路:优化多次遍历,利用双指针,指针2先走n步,然后指针2和指针1再一起向后走,直至指针2遍历结束指向空,此时指针1在指针2前n个结点的位置,即倒数第n个结点,删掉指针1即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

潍坊数字孪生元宇宙赋能智能制造,助力工业制造业数字化转型

潍坊工业元宇宙数字孪生赋能智能制造&#xff0c;助力工业制造业数字化转型。在当今数字化时代&#xff0c;工业智能制造已成为制造业发展的必然趋势。潍坊市作为山东省的重要工业基地&#xff0c;积极探索数字孪生技术在工业智能制造领域的应用&#xff0c;为制造业企业数字化…

ant-design-vue Notification 通知提醒框 内容换行

直接上代码 const msg errArr.map((message, index) > ${index 1}. ${message};) notification.open({message: ${statu.moduleName} 告警信息,description: () > {// 将msg所有;替换为\n换行符const res msg.replaceAll(;, \n)return h(pre,{style: {overflow: scro…

Transformer简单理解

目录 一、CNN存在的问题&#xff1a;二.Transformer整理架构分析&#xff1a;1.Linear Projection of Flattened Patches层形成Patch&#xff1a;2.对每个Patch进行位置编码Position Embedding&#xff1a;3.Transformer Encoder: 三.公式解读&#xff1a; 一、CNN存在的问题&a…

为什么使用 atan2(sin(z), cos(z)) 进行角度归一化?

文章目录 为什么使用 atan2(sin(z), cos(z)) 进行归一化&#xff1f;为什么归一化后的角度等于原始角度&#xff1f; atan2 方法返回 -π 到 π 之间的值&#xff0c;代表点 (x, y) 相对于正X轴的偏移角度。这个角度是逆时针测量的&#xff0c;以弧度为单位。关于 atan2 函数为…

【JAVA WEB】 Filter过滤器详解

目录 1&#xff0c;Filter 1.1 Filter概述 1.2 Filter快速入门 1.2.1 开发步骤 1.2.2 代码演示 1.3 Filter执行流程 1.4 Filter拦截路径配置 1.5 过滤器链 1.5.1 概述 1.5.2 代码演示 1.5.3 问题 1.6 案例 1.6.1 需求 1.6.2 分析 1.6.3 代码实现 1.6.3.1 创建Fi…

ERP系统怎么选 企业ERP管理系统选型建议

市面上有众多的ERP系统&#xff0c;而由于不同软件供应商的发展策略不同&#xff0c;导致不同ERP系统的侧重点也不同。例如有针对企业某一类管理需求的ERP系统&#xff0c;例如财务管理软件&#xff0c;进销存管理软件&#xff0c;仓库管理软件等。还有针对企业资源整合&#x…

element-ui表单验证同时用change与blur一起验证

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 当审批时不通过审批意见要必须输入&#xff0c; 1&#xff1a;如果用change验证的话删除所有内容时报错是massage的提示&#xff0c;但是在失去焦点的时候报错就成了英文&#xff0c;如下图&#xf…

【iOS】数据存储方式总结(持久化)沙盒结构

在iOS开发中&#xff0c;我们经常性地需要存储一些状态和数据&#xff0c;比如用户对于App的相关设置、需要在本地缓存的数据等等&#xff0c;本篇文章将介绍六个主要的数据存储方式 iOS中数据存储方式&#xff08;数据持久化&#xff09; 根据要存储的数据大小、存储数据以及…

计算机毕业设计 | SpringBoot宠物店管理系统(附源码)

1&#xff0c;绪论 项目背景 我国已经成为世界第二大经济体&#xff0c;经济实力高速发展以及百姓生活水平的普遍提高&#xff0c;不断地要求企业提供更加多元化的娱乐方式&#xff0c;更加快速和方便的服务&#xff0c;因此对宠物行业也提出了更加严格的要求&#xff0c;如管…

【NI国产替代】NI‑9232,3通道,102.4 kS/s/ch,±30 V,C系列声音与振动输入模块

3通道&#xff0c;102.4 kS/s/ch&#xff0c;30 V&#xff0c;C系列声音与振动输入模块 NI‑9232可以测量来自集成电子压电(IEPE)和非IEPE传感器的信号&#xff0c;例如加速度计、转速计和接近式探针。 NI‑9232还可兼容智能TEDS传感器。\n\nNI‑9232集成了软件可选的AC/DC耦合…

Window——安装nacos

1、Git拉取项目 官方地址&#xff1a;https://nacos.io/zh-cn/ git clone https://github.com/alibaba/nacos.git2、进入项目执行命令安装&#xff08;需要maven&#xff09; Maven下载指引&#xff1a;https://blog.csdn.net/qq812457115/article/details/117451334 mvn -Prel…

JRT核心竞争力

如果说JRT业务脚本化和发部署简单和打印导出客户端都不足以抵挡Spring用的人多的优势的话。那么这一篇让DolerGet给你一个选择JRT的理由&#xff0c;借助JRT自我实现的ORM&#xff0c;JRT有能力完全把控更新数据和删除数据的口径&#xff0c;和能够准确知道哪些是热点数据&…

UDP传输总丢包?常用的解决方式在这里!

UDP是一种无连接的协议&#xff0c;传输数据时不建立连接&#xff0c;因此可能导致数据包丢失。UDP丢包是指在传输过程中由于各种原因导致数据包未能到达目的地。UDP丢包会影响传输的质量和效率&#xff0c;导致数据损失、延迟&#xff0c;甚至导致传输失败。本文将分析UDP丢包…

guns项目 Failed to register @ServerEndpoint class 问题

问题发生所在 socket-business-websocket-7.2.4.jar tomcat发布测试的时候报Failed to register ServerEndpoint class &#xff0c;查询jar报主要是WebSocketServer 类加载有问题&#xff0c;把jar报中该类注掉&#xff0c;重新实现这个类&#xff0c;删除Component注解问题&…

Linux信号之信号的保存

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 目录 一、阻塞信号 1.信号递达、未决、阻塞 2.内核…

yolov1:背景介绍与算法精讲

目录 一、背景介绍1.1 yolo发展历史1.2 作者介绍 二、算法精讲2.1 预测阶段2.2 训练阶段 三、论文细节 一、背景介绍 其实在写这篇博客的时候yolov1~yolov8的所有网络结构以及算法思想和源码都已经研究很久了&#xff0c;回过头继续读v1会发现有很多细节是自己没有留意的&#…

Linux上新部署的项目jar包没有生效

今天公司新安排了一个项目&#xff0c;这里简称项目A&#xff0c;需要新增两个功能&#xff0c;我这边完成之后&#xff0c;跟前端对接好了&#xff0c;调试也没有问题。 然后把项目打包上传到测试服务器上&#xff0c;重新启动项目&#xff0c;发现项目A新增的接口没有生效&a…

多变量线性回归

一、多维特征 目前为止&#xff0c;我们探讨了单变量/特征的回归模型&#xff0c;现在我们对房价模型增加更多的特征&#xff0c;例如房间数、楼层等&#xff0c;构成一个含有多个变量的模型&#xff0c;模型中的特征为。 增添更多特征后&#xff0c;我们引入一系列新的注释&am…

【数据结构和算法】奇偶链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;分离节点后合并 三、代码 3.1 方法一&#xff1a;分离节点后合并 四、复杂度分…

shopee、Lazada、速卖通测评自养号技术,当天注册当天直接下单

自养号测评&#xff08;补单&#xff09;技术对跨境平台如shopee、Lazada、速卖通、ebay、wish、mercari、Newegg等是否有用&#xff1f; 随着越来越多的跨境电商进入市场&#xff0c;并且考虑到亚马逊对大卖家的严格监管&#xff0c;这无疑为其他跨境电商平台和独立站市场带来…