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.mfbz.cn/a/206106.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于php的求书网的设计与实现

摘 要 伴随着信息技术的飞速发展&#xff0c;以及百姓生活品质的改善&#xff0c;电商也成为人们日常生活不可或缺的构成要素。网上商城已然成为了电子商务最最普遍的一种形式&#xff0c;已被大家逐渐接受并且去实施。所以本文提出的求书网站开发能够充分适合当今形势&#x…

目标检测——SPPNet算法解读

论文&#xff1a;Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 作者&#xff1a;Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun 链接&#xff1a;https://arxiv.org/abs/1406.4729 目录 1、算法概述2、Deep Networks with Spatia…

11月30日作业

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数 #include <iostream>using namespace std;class …

20个Python源码项目下载

20个很不错的Python项目源码&#xff0c;其中包括适合毕业设计的项目。这些资源中涵盖了Django 3版本的项目&#xff1a; DjangoMysqlBulma实现的商场管理系统源码 PythonDjango实现基于人脸识别的门禁管理系统 PythonFlaskMySQL实现的学生培养计划管理系统 Python大熊猫主题人…

qt 5.15.2压缩和解压缩功能

qt 5.15.2压缩和解压缩功能 主要是添加qt项目文件.pro内容&#xff1a; 这里要先下载quazip的c项目先编译后引入到本项目中/zip目录下 INCLUDEPATH ./zip CONFIG(debug, debug|release) {win32:win32-g: PRE_TARGETDEPS $$PWD/zip/libquazipd.awin32:win32-g: LIBS -L$$PWD…

文件格式扩展名转换:将图片png扩展名批量改为jpg的方法

在处理大量图片文件时&#xff0c;可能会遇到需要将文件格式扩展名进行转换的情况。比如&#xff0c;将图片文件从PNG格式转换为JPG格式。这不仅可以节省存储空间&#xff0c;还可以提高图片加载速度&#xff0c;特别是在网页设计中。本文详解如何将PNG图片批量转换为JPG格式的…

2023-11-30 LeetCode每日一题(确定两个字符串是否接近)

2023-11-30每日一题 一、题目编号 1657. 确定两个字符串是否接近二、题目链接 点击跳转到题目位置 三、题目描述 如果可以使用以下操作从一个字符串得到另一个字符串&#xff0c;则认为两个字符串 接近 &#xff1a; 操作 1&#xff1a;交换任意两个 现有 字符。 例如&…

LeetCode Hot100 3.无重复字符的最长子串

题目&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 代码&#xff1a; class Solution {public int lengthOfLongestSubstring(String s) {char[] arr s.toCharArray(); // 转换成 char[] 加快效率&#xff08;忽略带来的空间…

[操作系统] 文件管理

文章目录 5.1 磁盘调度算法1. 先来先服务算法( First Come First Served, FCFS) 算法2. 最短寻道时间优先算法( Shortest Seek Time First, SSTF) 算法3. 扫描算法( SCAN ) 算法4. 循环扫描算法( Circular Scan, CSCAN ) 算法5. LOOK 与 CLOOK 算法 5.2 进程写文件时&#xff0…

Goby 漏洞发布| CrushFTP as2-to 认证权限绕过漏洞(CVE-2023-43177)

漏洞名称&#xff1a; CrushFTP as2-to 认证权限绕过漏洞&#xff08;CVE-2023-43177&#xff09; English Name&#xff1a;CrushFTP as2-to Authentication Permission bypass Vulnerability (CVE-2023-43177) CVSS core: 9.8 影响资产数&#xff1a; 38695 漏洞描述&…

【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…

商家门店小程序怎么做?门店小程序的优势和好处

生活服务类商家在当前数字化时代&#xff0c;越来越认识到门店小程序的重要性。门店小程序不仅为商家提供了一个在线展示的窗口&#xff0c;更为其打造了一个与消费者直接互动的平台。有了门店小程序&#xff0c;商家可以更加便捷地管理商品信息、订单流程&#xff0c;同时还能…

Linux常用命令----history命令

文章目录 在Linux中&#xff0c;history命令是一个极其有用的工具&#xff0c;它可以帮助用户查看和管理之前执行过的命令历史。这个功能对于快速查找和重用之前的命令特别有帮助。下面&#xff0c;我们将通过一些实例&#xff0c;详细介绍history命令的使用方法。 1. 基本使用…

【稳定检索|投稿优惠】2024年经济管理与安全科学国际学术会议(EMSSIC 2024)

2024年经济管理与安全科学国际学术会议(EMSSIC 2024) 2024 International Conference on Economic Management and Security Sciences(EMSSIC 2024) 一、【会议简介】 2024年经济管理与安全科学国际学术会议(EMSSIC 2024)&#xff0c;将于繁华的上海城召开。这次会议的主题是“…

前端:实现div的隐藏与显示

效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

WSL2 docker GUI 界面

在 WSL2 docker 中运行GUI界面。 具体流程和远程显示Ubuntu界面类似&#xff0c;链接, 更简单一点&#xff0c; 少了 ssh 的部分。 安装好wsl2 和 docker wsl2 运行GUI程序&#xff0c;windows 会默认弹出窗口。 可以安装 gedit 测试一下 windows 下载并运行 Xlaunch. 运行 d…

力扣202题 快乐数 双指针算法

快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&#…

LLM 分布式训练框架 | DeepSpeed与Accelerate

&#x1f680; 简单记录下根据网上资料&#xff08;如Reference中所列&#xff09;所学到的一些知识&#xff0c;这里主要介绍的是deepspeed分布式训练框架相关概念。 &#x1f604;小日记&#xff1a;今天太舒服了&#xff0c;早上跑了6km&#xff0c;晚上吃了养生菌菇火锅~ …

亚马逊云科技re:Invent Peter DeSantis演讲,数据规模拓展无极限引领Serverless构建之路

re:lnvent 2023 Peter DeSantis主题演讲&#xff0c;数据规模拓展无极限引领Serverless构建之路&#xff08;Road to Serverless&#xff09;。 Logical Qubit全新发布&#xff1a;量子计算硬件&#xff0c;6倍的量子纠错效率提升。 Amazon全新发布Redshift Serverless&#xf…

通过C#获取Windows设置的夏令时开关

C#获取Windows夏令时开关 // 获取所有的时区信息 var allTimeZones TimeZoneInfo.GetSystemTimeZones().ToList();通过接口可以看到, 字段SupportsDaylightSavingTime代表是否支持配置夏令时 // 获取当前Window设置的时区 var tmpLocal TimeZoneInfo.Local;但是取Local 信息…
最新文章