C语言每日一题(42)删除链表的倒数第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

思路分析

关于这道题,有两种思路和三种不同的方法,我们来一一分析。

思路1:快慢指针法

我们之前做过一题,找出链表的倒数第N个结点,我们可以在此基础上进行,找到第N个结点,然后删除即可,但这里涉及到一些特殊情况:

1.当链表长度只有一个,且n=1时,如果直接释放头结点的话会野指针;

2.当需要删除的结点是头结点,直接删除的话会丢失后面的结点。

这里分成两种方法进行实现:

1.带一个哨兵位

我们发现,往往与删除功能有关的题都会需要考虑链表为空的情况,但只要定义一个哨兵位指向头结点就能很好解决,减少代码量,提供效率。

有了哨兵位,删除也方便了许多。我们通过快慢指针法遍历链表,得到slow指向的结点就是需要删除的结点,但此时还得需要获得它的前驱结点,这时就得定义第三个指针在遍历的时候指向它的前驱结点,且又得考虑链表为空的情况(在方法2不带哨兵位会进行解释)但如果有了哨兵位,我们可以让快指针从头结点开始,二慢指针从哨兵位开始,遍历结束后,slow指针的下一个就是要删除的结点,相当于不找删除结点,而是找删除结点的前驱结点,直接指向下一个结点的下一个完成删除。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* dummy=(struct ListNode*)malloc(sizeof(struct ListNode));//哨兵位,不存储有效数据,用来解决链表为空的情况dummy->val=0;dummy->next=head;struct ListNode* fast=head;//快指针struct ListNode* slow=dummy;//慢指针while(n--){if(fast==NULL){return NULL;}fast=fast->next;}while(fast){fast=fast->next;slow=slow->next;}slow->next=slow->next->next;struct ListNode* ans=dummy->next;free(dummy);//动态开辟的空间记得释放return ans;}

2.不带哨兵位

有些小伙想要锻炼自己的代码能力,一般是不喜欢用哨兵位,貌似有点投机取巧的感觉(作者本人是这么想的。。。),下面我们来介绍一下不带哨兵位的做法。

既然不带哨兵位,我们就需要第三个指针在遍历时保存删除结点的前驱结点,同时链表为空和头结点为野指针的情况要逐一考虑。

当我们需要删除的结点是头结点,就需要将head指针移动到下一个当作新的头结点再将原来的结点释放。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* fast=head;struct ListNode* slow=head;struct ListNode* prev=head;while(n--){if(fast==NULL){return NULL;}fast=fast->next;}while(fast){prev=slow;slow=slow->next;fast=fast->next;}if(slow==head){head=slow->next;free(slow);}else{prev->next=slow->next;free(slow);}return head;}

 思路2:链栈

这是力扣官方的一个解题思路,只需要遍历一次即可。

步骤就是将链表的所有元素入栈,根据n的值来决定出栈的次数,出栈完后,会发现此时栈顶元素就是需要删除结点的前驱结点,之后进行删除。

链表入栈的方式和链表的头插是类似的,为了增加效率,我们带一个哨兵位(嘻嘻)。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/struct Stack//链栈类{struct ListNode* val;//存储的元素类型是链表struct Stack* next;//指向下一个栈类};
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* dummy=(struct ListNode*)malloc(sizeof(struct ListNode));//哨兵位初始化dummy->val=0;dummy->next=head;struct ListNode* cur=dummy;struct Stack* stk=NULL;while(cur)//入栈{struct Stack* tmp=(struct Stack*)malloc(sizeof(struct Stack));//基于头插法实现tmp->val=cur;tmp->next=stk;stk=tmp;cur=cur->next;}while(n--)//出栈{struct Stack* tmp=stk->next;free(stk);stk=tmp;}struct ListNode* prev=stk->val;//栈顶元素就是删除元素的前驱结点prev->next=prev->next->next;//进行删除struct ListNode* ans=dummy->next;//释放开辟的哨兵位free(dummy);return ans;}

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

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

相关文章

稳定的音频来了 — 使用人工智能创作音乐(for free)

今天&#xff0c;以稳定扩散&#xff08;Stable Diffusion&#xff09;和StableLM等开源AI工具和模型而闻名的Stability AI公司推出了其首个音乐和声音生成AI产品——StableAudio。音乐产业以其难以打入而闻名。即使您拥有才华和动力&#xff0c;您仍然需要创作和制作音乐所需的…

tornado模版注入 [护网杯 2018]easy_tornado 1

打开题目 打开flag.txt 告诉我们flag在 /fllllllllllllag下 打开welcome.txt 我们看到了render渲染函数&#xff0c;联想到ssti 打开hints.txt 然后我们留意到每个打开url上面都有filehash 告诉我们如果想要访问/fllllllllllllag下的flag文件&#xff0c;是需要filehash这个GE…

二、shell编程快速入门

目录 1、入门示例 2、解释器 3、shell脚本执行方式 3.1 方式一&#xff1a;sh执行脚本 3.2 方式二&#xff1a;工作目录执行 3.3 方式三&#xff1a;绝对路径执行 4、shell的数据类型 4.1 字符串 4.2 整数型 1、入门示例 以下所有操作都在/export/shell目录下进行&am…

dapper+mysql查询报Error parsing column 0 (Id=<null>)

之前的分页接口都是正常的&#xff0c;突然就报错了Error parsing column 0 (Id<null>) {"error": {"code": null,"message": "Error parsing column 0 (Id<null>)","details": "DataException: Error pa…

【Web】UUCTF 2022 新生赛 个人复现

目录 ①websign ②ez_rce ③ez_upload ④ez_unser ⑤ezsql ⑥ezpop ⑦funmd5 ⑧phonecode ⑨ezrce ①websign 右键打不开&#xff0c;直接抓包发包看源码 ②ez_rce “反引号” 在PHP中会被当作SHELL命令执行 ?codeprintf(l\s /); ?codeprintf(ta\c /ffffffffffl…

Spring Security 的使用

一、简介 1.1、Spring Security 相关概念 1.过滤器链&#xff08;Filter Chain&#xff09; 基于Servlet过滤器&#xff08;Filter&#xff09;处理和拦截请求&#xff0c;进行身份验证、授权等安全操作。过滤器链按顺序执行&#xff0c;每个过滤器负责一个具体的安全功能。 …

入门Python+Vue 全栈开发可视化BI数据项目几个要点总结

随着数据的快速增长和业务的复杂性&#xff0c;越来越多的企业开始关注数据分析和可视化。在本文中&#xff0c;我们将介绍如何使用Python和Vue进行全栈开发&#xff0c;构建一个可视化BI数据项目&#xff0c;并总结几个关键要点。 首先&#xff0c;Python是一种强大而灵活的编…

利用Linux中的iptables进行网络代理配置

作为资深爬虫技术员&#xff0c;爬虫需要代理IP池介入这是众所周知的。今天我将用我毕生所学&#xff0c;谈谈linux中使用iptables工具来进行网络配置&#xff0c;并通过linux系统创建属于自己的ip库池&#xff0c;如有错误望各位大佬指正。 我们知道&#xff0c;在Linux中&am…

java-Swing界面简析

一、简析&#xff1a; 调用java提供的 java.swing包下的各种类可以实现界面中的各种组件(比如输入框、密码框按钮、单选框、复选框等) 二、java.swing包的关键类&#xff1a; 顶层容器&#xff1a;Jframe(窗口) 中间容器&#xff1a;Jpanel(面板) 基本控件&#xff1a; I…

FL Studio水果软件最新21.1.1.3750破解版下载

FL Studio是一款流行的图像线软件制作和编辑音频文件。作为一款领先的创新产品&#xff0c;该软件能够满足在创作音乐方面的需求。有了这个产品&#xff0c;可以完成制作音乐的整个过程。可以使用这个软件进行写作&#xff0c;编辑&#xff0c;录音&#xff0c;编辑和混合和掌握…

【服务部署】常用内网穿透方案

一、前言 由于一些开发及使用需求&#xff0c;需要将内网机器端口映射到公网&#xff0c;达到公网访问内网环境的目的 本文主要介绍几种常用的内网穿透方案 ssh远程端口转发 部署简单&#xff0c;无需额外安装软件包 frp反向代理 功能配置丰富&#xff0c;部署相对复杂&#…

uni-app 自带返回方法onBackPress,返回上一级并且刷新页面内容获取最新的数据

onBackPress 返回上一级并且刷新页面内容获取最新的数据 onBackPress 方法是uinapp自带返回键方法&#xff0c;也就是在app和H5返回键 onBackPress() {setTimeout(() > {uni.switchTab({url: /pages/Users/index,})}, 300)return true}, methods: {}在这里 uni.switchTab…

Linux 命令pwd

命令作用 pwd是Linux中一个非常有用而又十分简单的命令&#xff0c;pwd是词组print working directory的首字母缩写&#xff0c;即打印工作目录&#xff1b;工作目录就是你当前所处于的那个目录。 pwd始终以绝对路径的方式打印工作目录&#xff0c;即从根目录&#xff08;/&am…

LeetCode(45)最长连续序列【哈希表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 最长连续序列 1.题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&a…

7.23 SpringBoot项目实战【评论】

文章目录 前言一、编写控制器二、编写服务层三、Postman测试前言 我们在 7.4 和 7.20 都曾实现过 评论列表,本文我们继续SpringBoot项目实战 评论 功能。逻辑实际相当Easy:一个学生 对 任意书 都可以 多次评论,但需要经过审核! 回顾一下 4.2 的数据库设计,学生图书评论表…

vue3+element-plus+vue-cropper实现裁剪图片上传

1.vue3element-plusvue-cropper实现裁剪图片 element-UI官网element-plus官网vue-croppervue3使用vue-cropper安装&#xff1a;npm install vue-croppernext 2.vue-cropper插件&#xff1a; <vue-cropper :img"option.img" /><script setup>import {reac…

STM32F407-14.3.7-01PWM输入模式

PWM 输入模式 此模式是输入捕获模式的一个特例。其实现步骤与输入捕获模式基本相同&#xff0c;仅存在以下不同之处&#xff1a; 例如&#xff0c;可通过以下步骤对应用于 TI1① 的 PWM 的周期&#xff08;位于 TIMx_CCR1⑨ 寄存器中&#xff09;和占空 比&#xff08;位于 …

认识JVM 一个Java文件的JVM之旅

准备 我是一个java文件&#xff0c;如何实现我的功能呢&#xff1f;需要去JVM(Java Virtual Machine)这个地方旅行。 变身 我高高兴兴的来到JVM&#xff0c;想要开始JVM之旅&#xff0c;它确说&#xff1a;“现在的我还不能进去&#xff0c;需要做一次转换&#xff0c;生成c…

VUE2+THREE.JS 模型上方显示信息框/标签(CSS3DSprite精灵模型)

THREE.JS 模型上方显示信息框/标签---CSS3DSprite精灵模型 1.CSS2DRenderer/CSS3DRenderer/Sprite的优劣2.实现模型上方显示信息框2.1 引入2.2 初始化加载的时候就执行此方法2.3 animate循环执行2.4 获取设备状态并在每个设备上显示设备状态2.5 样式 CSS3DSprite精灵模型面向摄…

python中的函数定义

默认参数 注&#xff1a; 在Python中&#xff0c;print(x, and y both correct)是一条打印语句&#xff08;print statement&#xff09;&#xff0c;用于将一条消息输出到控制台或终端。它的作用是将变量x的值和字符串and y both correct同时输出到屏幕上。 在这个语句中&…