算法力扣刷题记录十【19.删除链表的倒数第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

进阶:

你能尝试使用一趟扫描实现吗?

第一次尝试

先不考虑进阶,看如何实现。

思路:重点是什么找到倒数第n个节点。

  • 删除节点操作:用cur指向被删除节点的前一个节点。所以肯定得要一个虚拟头节点
  • 初始:cur = dummy_node;判断cur是不是在删除目标的前一个节点的位置?
  • 用search = cur,将search后移n位,看search->next是否为空:
    • n=1,将cur位置后移1位,search->next==nullptr;
    • n=2,将cur位置后移2位,search->next==nullptr;
    • n=3,将cur位置后移3位,search->next==nullptr;
    • 依次类推

代码实现(测试通过)

/*** 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_node = new ListNode(0,head);ListNode* cur = dummy_node;while(cur->next != nullptr){ListNode* search = cur;for(int i=0;i < n ;i++){search = search->next;}if(search->next == nullptr){//交换ListNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;break;}cur = cur->next;}head = dummy_node->next;delete dummy_node;return head;}
};

检查:head=nullptr,符合逻辑。n=1,for循环条件判断正确。所以通过测试。
分析时间复杂度

while循环最差情况要遍历整个链表长度,for循环最差情况下执行n*(n+1)/2次,所以整体时间复杂度O(n^3)。

进阶

尝试使用一趟扫描。
思路:同样是线性结构,数组里面有快慢指针。这里能不能也用快慢指针?类似滑动窗口?

代码实现

/*** 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_node = new ListNode(0,head);ListNode* slow = dummy_node;ListNode* fast = dummy_node->next;int num = 1;//计数链表总长度if(slow->next != nullptr){while(fast->next != nullptr){fast = fast->next;num++;}if(num < n ){	//完善n超出链表长度,此时不删除,返回原链表,抛出异常throw out_of_range("n > list_length");return head;}for(int i = 0;i < num-n ;i++){slow = slow->next;}ListNode* tmp = slow->next;slow->next = slow->next->next;delete tmp;}head = dummy_node->next;delete dummy_node;return head;}
};

思路正确:

  • 让fast先找到链表的最后一个元素,同时计数num,得到链表的总元素。
  • 收缩窗口,移动slow,移动num-n次,指向删除目标的前一个节点。slow到达位置之后,开始链表删除操作。

思路来源:个人博客【算法力扣刷题记录四【长度最小的子数组】】,学习到滑动窗口,同样是线性规则,所以借来使用。

进阶成功!!!


代码随想录学习

学习内容

同样是定义fast和slow,但过程也有区别。
我的操作:fast直接走到链表结尾,得出链表节点总数,再让slow后移num-n,到达删除目标的前一个位置。
参考操作

  • fast先走n步,这样窗口内包含n个节点,再让fast和slow同时移动,窗口内始终保持n个节点,当fast=nullptr时,slow恰好指向倒数第n个节点。
  • 由于删除操作,需要slow指向倒数第(n+1)个节点,所以修正让fast先走n+1步.

代码实现:

/*** 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_node = new ListNode(0,head);ListNode* slow = dummy_node;ListNode* fast = dummy_node;while(fast != nullptr  && n >= 0){ //n >= 0确保fast先走了n+1步fast = fast->next;n--;}if(n < 0){  //如果输入的n大于链表长度,n<0才算fast走到位,否则fast没走到位,但又已经到达链表尾部。返回原链表,不操作。不然就会把头节点删除,因为slow没有移动。while (fast != nullptr ){fast = fast->next;slow = slow->next;}ListNode* tmp = slow->next;slow->next = slow->next->next;delete tmp;}else{			//当n输入超过链表长度,抛出异常。throw out_of_range("n out of list range");}head = dummy_node->next;delete dummy_node;return head;}
};

参考答案在第11行有操作空指针的风险,只是力扣用例没有检出来。
所以我在if(n < 0)可以保证输入的n小于链表长度,更完善。如果输入n超过链表长度,抛出out_of_range异常

可以回过头看[进阶]目录下代码完善。


总结

  • 删除链表节点:加虚拟头结点
  • “滑动窗口”思路:个人和参考,两种操作。
  • 代码随想录参考11行,个人认为有缺陷,没有保证n小于链表长度,作了补充。

(欢迎指正,转载标明出处)

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

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

相关文章

服务器出现意外情况。(Exception from HRESULT: 0x80010105(RPC E SERVERFAULT))

这种情况一般出现在excel2007版本&#xff0c;下载了什么阅读器之类的 2007改不了这个加载项&#xff0c;需要重装一个其他版本&#xff08;2010版本可以&#xff09; 然后如下操作修改为COM加载项

Python湍流隐式模型耗散粘性方程和大涡流模拟

&#x1f3af;要点 &#x1f3af;达朗贝尔一维波动通解&#xff0c;二维变速模拟 | &#x1f3af;达朗贝尔算子解双曲波形微分方程 | &#x1f3af;耗散系统粘性伯格斯方程快速傅里叶变换算法 | &#x1f3af;二维线性和非线性对流扩散解和湍流隐式建模 &#x1f4dc;偏微分方…

[行业原型] Web端原型案例:康欣医疗后台管理系统

​医疗管理系统是一个业务复杂&#xff0c;功能庞大的系统&#xff0c;以下为HIS医院管理系统的常见模块&#xff0c;供大家参考。 本周为大家带来Web端原型案例&#xff1a;康欣医疗后台管理系统&#xff0c;先上原型&#xff1a; 完整文档加班主任微信号 添加班主任回复 “1…

8个Unity开发高手都在用的秘密技巧!

1. 不要重新发明轮子&#xff0c;使用内置的引擎工具 在使用任何引擎时&#xff0c;比如Unity或Unreal Engine&#xff0c;一些开发者&#xff0c;主要是来自计算机科学领域的开发者&#xff0c;可能会倾向于从头开始开发大型算法或结构&#xff0c;而不去了解引擎中是否已经存…

我给我的学校写了个校园墙小程序

目录 前言 正文 事先声明 项目介绍 关于Github的一些点 ①贡献值的记录 ②Github中的Project是什么 ③Release和Package有什么区别 ④开源许可证之间的区别 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Securit…

vector的自实现(迭代器失效问题)与继承续讲

引子&#xff1a;在生活中&#xff0c;我们使用vector很频繁&#xff0c;我们是不是可以自己来实现一个呢&#xff1f;&#xff0c;其实也不难&#xff0c;我们在学过数据结构&#xff0c;就很easy啦&#xff01; As we all kowmn,vector基础有以下函数&#xff01; from my …

git 初基本使用-----------笔记(结合idea)

Git命令 下载git 打开Git官网&#xff08;git-scm.com&#xff09;&#xff0c;根据自己电脑的操作系统选择相应的Git版本&#xff0c;点击“Download”。 基本的git命令使用 可以在项目文件下右击“Git Bash Here” &#xff0c;也可以命令终端下cd到指定目录执行初始化命令…

YOLOv1 中的一些计算

YOLOv1 中的一些计算 位置参数计算 在训练过程中&#xff0c;需要分别计算真实框的位置参数 t x t_x tx​、 t y t_y ty​、 w w w、 h h h。 已知真实框的左上角点和右下角点坐标&#xff1a; g t [ x 1 , y 1 , x 2 , y 2 ] gt [x_1, y_1, x_2, y_2] gt[x1​,y1​,x2​…

vue elementui简易侧拉栏的使用

目的&#xff1a; 增加了侧拉栏&#xff0c;目的是可以选择多条数据展示数据 组件&#xff1a; celadon.vue <template><div class"LayoutMain"><el-aside :width"sidebarIsCollapse ? 180px : 0px" class"aside-wrap"><…

【机器学习】深度概率模型(DPM)原理和文本分类实践

1.引言 1.1.DPM模型简介 深度概率模型&#xff08;Deep Probabilistic Models&#xff09; 是结合了深度学习和概率论的一类模型。这类模型通过使用深度学习架构&#xff08;如神经网络&#xff09;来构建复杂的概率分布&#xff0c;从而能够处理不确定性并进行预测。深度概率…

Linux通过expect实现免交互

免交互 Here Document 用于将多行字符串直接传递给命令的方式&#xff0c;不需要人为交互命令界面&#xff0c;实现免交互 当使用Here Document操作文件时&#xff0c;需要借助一个文件结束符 EOF&#xff1a;文件结束符 示例 在脚本文件中写入以下内容 <<&#x…

AFLNet入门教学——测试RTSP协议实现Live555(Ubuntu)

1、简介 本文旨在使用AFLNet对RTSP协议实现Live555进行模糊测试。实验环境为&#xff1a;Ubuntu22.04.4AFLNet安装参考&#xff1a;AFLNet入门教学——安装&#xff08;Ubuntu22.04.4&#xff09;-CSDN博客 2、安装Live555 本次实验采取的是live555在2018年8月28日上传的版本…

nacos漏洞汇总

1 nacos介绍 1.1 nacos是啥 Alibaba Nacos是阿里巴巴推出来的一个新开源项目&#xff0c;是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。致力于帮助发现、配置和管理微服务。Nacos提供了一组简单易用的特性集&#xff0c;可以快速实现动态服务发现、服…

【Knowledge Graph Context-Enhanced Diversified Recommendation(MSDM2024)】

Knowledge Graph Context-Enhanced Diversified Recommendation 摘要 推荐系统&#xff08;RecSys&#xff09;领域已被广泛研究&#xff0c;以通过利用用户的历史交互来提高准确性。 尽管如此&#xff0c;这种对准确性的持续追求常常导致多样性的减少&#xff0c;最终导致众所…

全网最强MyBatisPlus教程 | 万字长文爆肝MyBatisPlus

MyBatisPlus 今日目标 基于MyBatisPlus完成标准Dao的增删改查功能 掌握MyBatisPlus中的分页及条件查询构建 掌握主键ID的生成策略 了解MyBatisPlus的代码生成器 1&#xff0c;MyBatisPlus入门案例与简介 这一节我们来学习下MyBatisPlus的入门案例与简介&#xff0c;这个和其他…

在线AI聊天对话机器人,答你所问!

随着AI人工智能技术的不断进步&#xff0c;AI聊天对话机器人已经成为我们日常生活中常用的工具。这些智能助手不仅能够提供信息查询、生活娱乐、学习辅导等服务&#xff0c;还能通过自然语言处理和机器学习技术理解用户的需求&#xff0c;提供个性化的回答和建议。下面小编就和…

选择第三方软件测试机构做验收测试的好处简析

企事业单位在自行开发完软件系统或委托软件开发公司生产软件之后&#xff0c;有一个必经流程就是验收测试&#xff0c;以验证该产品是否符合用户需求、是否可以上线。为了客观评估所委托生产的软件质量&#xff0c;第三方软件测试机构往往成为企事业单位做验收测试的首选&#…

如何有效降低云消息使用成本?涂鸦Pulsar云消息史诗级大更新来了!超级干货攻略快收藏

月末了&#xff0c;相信大家都会有信用卡额度超支的担忧&#xff0c;生怕一不留神就会超出预算&#xff0c;并且事后还需要仔细核对消费情况。类似的焦虑&#xff0c;也会出现在使用涂鸦 Pulsar 云消息服务时。虽然涂鸦 Pulsar 云消息能满足开发者对设备各类事件实时性和持久化…

ADI-DSP|在指定内存写入数据

一、LDF文件设置内存空间 user_data_test { TYPE(BW RAM) START(0x00380010) END(0x0039bfff) WIDTH(8) }//usr data dxe_user_data_bw BW{INPUT_SECTION_ALIGN(4)INPUT_SECTIONS( $OBJS_LIBS(user_data) )} > user_data_test 二、在C文件中设置数据 /************…

使用LabVIEW和示波器测试IGBT参数

使用LabVIEW和示波器测试绝缘栅双极型晶体管&#xff08;IGBT&#xff09;参数的综合解决方案。过程包括硬件设置、示波器和其他必要设备的配置&#xff0c;以及开发LabVIEW程序以自动化数据采集、过滤、关键参数计算和结果显示。该方法确保了IGBT测试的准确性、可靠性和高效性…