LeetCode单链表OJ题目做题思路分享

目录

    • 移除链表元素
    • 链表的中间节点
    • 链表中倒数第K个节点
    • 合并两个有序链表

移除链表元素

链接: link
题目描述:
在这里插入图片描述
思路分享

我们上个博客分享了第一种方法,下面我们分析第二种方法:思路就是将每一个不等于我们要删除的值的节点依次尾插。
我们要记录我们尾插之后的新的头,以便于我们将新链表的头返回。
尾插的情况有以下两种:
如果当前要插入的值不是我们要删除的值时,我们要判断以下两种情况
1.链表没有元素,是空链表,这时就需要我们将链表新的头赋值为当前节点的值,并且此时的尾也指向链表新的头。newhead=tail=cur。
2.链表当中没有元素,不是空链表时,将此节点直接插入到当前链表的尾部。tail->next = cur,tail = tail ->next
如果当前要插入的值是我们要删除的值时:
新定义一个节点用来保存我们要删除的节点,将cur指针指向下一个节点,再free掉我们定义的节点。struct ListNode* del = cur;cur = cur->next ;free(del);
这里要注意两个点:
1.每次进行插入操作之后,cur指针都要向下移动
2.为了避免出现野指针问题,每次进行插入结束后,尾指针的next域都要置空。

这里出现一个问题,cur指针向下移动和tail的next域置空的顺序:
在这里插入图片描述
为什么第一个是正确的呢?
解答:
下图步骤意思是:让newhead和tail指针指向节点1
在这里插入图片描述
此时cur指向1节点,cur的next依旧指向的是节点2,这一点并没有改变,所以cur=cur->next指向的是节点2。
但是如果先将tail->next置空,那么cur->next也是空,因为此时cur和tail指向的是同一个节点的,所以此时cur->next也是NULL,会导致cur=cur->next时候找不到下一个节点,所以我们的顺序必须是先cur=cur->next,再将tail->next置空。
代码实现:

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* cur = head;
    struct ListNode* newhead = NULL;
    struct ListNode* tail = NULL;
    while (cur)
    {
        if (cur->val != val)//和删除的值不相等
        {
            if (tail == NULL)//第一次插入
            {
                newhead = tail = cur;
            }
            else
            {
                tail->next = cur;
                tail = tail->next;
            }
            tail->next = NULL;
            cur = cur->next;

        }
        else//和删除的值相等
        {
            struct ListNode* del = cur;
            cur = cur->next;
            free(del);
        }
    }
    return newhead;
}

链表的中间节点

链接: link
题目描述:
在这里插入图片描述
题目思路:

快慢指针slow和fast
slow指针一次走一步,fast指针一次走两步。快指针速度是慢指针二倍,当快指针走到终点时,慢指针正好指向中间节点。
这里存在两种情况:刚好这两种情况可以作为我们循环的判断条件。
1.fast->next=NULL
在这里插入图片描述
2.fast=NULL
在这里插入图片描述

代码实现:

struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast&&fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

链表中倒数第K个节点

链接: link
题目描述:
在这里插入图片描述
题目思路:

本题我们的思路依然是一个快慢指针的问题
在这里插入图片描述

fast走到最后一个元素时,slow和fast同时向下一个节点移动,直到fast指向的位置为空,slow指向的位置就是我们要返回的元素。
本题我们要找倒数第1个节点,那么就以第一个节点为例,当slow和fast指针拉开1个举例时,两个指针同时向下移动,直到下面情况,slow指向的就是我们要找的值。
在这里插入图片描述
注意两点问题
1.如果链表的长度小于k的时候,也会造成fast空指针问题,所以在fast指针走k次的循环过程中,要保证不是因为单链表长度小于k而造成的空指针问题。
2.同时也要判断传过来的pListHead不为空或者k的值是否小于等于0,只要二者有一个满足,就要返回NULL。

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{
    if (!pListHead || k <= 0)//保证传过来的头不是空并且k的值是有效值
    {
        return NULL;
    }
    //开始两个指针同时指向链表的头
    struct ListNode* slow = pListHead;
    struct ListNode* fast = pListHead;
    while (k--)
    {
        if (fast)
        {
            fast = fast->next;
        }
        else
        {
            return NULL;//单链表长度小于K会造成fast空指针
        }
    }
    while (fast)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

合并两个有序链表

链接: link
题目描述:
在这里插入图片描述
在这里插入图片描述
题目思路:

两个指针同时指向List1和List2两链表头部。开始进行链接:
本题需要5个指针,List1,List2,tail,newhead
1、如果List1的值比List2的值小,那么List1的头就是我们合并后链表新的头,newhead = List1,之后让List1指向下一个节点,并且tail指向刚刚被插入的节点。
与此同时如果List2的值比List1的值小,那么List2的头就是我们合并后链表新的头,newhead = List2,之后让List2指向下一个节点,并且tail指向刚刚被插入的节点。
2、有了新链表的头之后,剩下的步骤就是比较两个节点的大小,那个节点值大,就将哪个节点拿下来尾插,并且让尾指针tail指向该尾插的节点。
3、在进行不断的尾插的过程中肯定会有一条链表为空,如果是List1为空,那么直接让tail->next链接List2,否则链接List1。
注意:
我们还要注意一点就是,很有可能给我们的两条链表有一条是空链表,此时只需要返回那条不为空的链表就好。

代码实现:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
        return list1;
    }
    if(list1==NULL&&list2==NULL)
    {
        return NULL;
    }
    struct ListNode* newhead = NULL;
    struct ListNode* tail = NULL;
    while(list1&&list2)
    {
        if(list1->val<list2->val)
        {
            if(newhead ==NULL)
            {
                newhead = tail = list1;
            }
            else
            {
                tail->next = list1;
                tail = tail->next;
            }
            list1 = list1->next;
        }
        else
        {
             if(newhead ==NULL)
            {
                newhead = tail = list2;
            }
            else
            {
                tail->next = list2;
                tail = tail->next;
            }
            list2 = list2->next;
        }
    }
    if(list1)
    {
        tail->next = list1;
    }
    if(list2)
    {
        tail->next = list2;
    }
    return newhead;
}

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

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

相关文章

如何快速获取已发表学术论文的期刊封面及目录(caj格式下载和caj转pdf)

目录 1 下载caj格式的封面和目录 2 CAJ格式的封面和目录转PDF格式 在进行职称评审或成果申报时&#xff0c;一般要求提交你发表的成果所在的期刊的当期封面和目录。本文就手把手带带你制作一个期刊目录。 重要提示&#xff1a;下载期刊封面和目录需要你有知网账号&#xff0…

Java读取Properties配置文件的6种方式

Java读取Properties的方式 项目结构&#xff1a;经典的maven项目结构 配置文件1和2内容一致&#xff1a; jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urlmysql://localhost:3306/database?useUnicodetrue&characterEncodingutf-8&serverTimezoneAsia/Shanghai jdbc.…

【深度学习】计算机视觉(13)——模型评价及结果记录

1 Tensorboard怎么解读&#xff1f; 因为意识到tensorboard的使用远不止画个图放个图片那么简单&#xff0c;所以这里总结一些关键知识的笔记。由于时间问题&#xff0c;我先学习目前使用最多的功能&#xff0c;大部分源码都包含summary的具体使用&#xff0c;基本不需要自己修…

找高清无水印视频素材,就上这9个网站。

推荐几个我的视频素材库&#xff0c;有免费、收费、商用&#xff0c;希望对大家有帮助&#xff01; 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频等各种素材。视频素材就有上千个&#xff0c;全部都很高清&…

unityt光线透射目标

介绍 在Unity中&#xff0c;光线透射目标通常指的是在场景中放置的一些物体&#xff0c;用于模拟光线从一个物体透过到另一个物体的效果。canvas子物体组件中&#xff0c;勾不勾选“光线透射目标”有什么区别&#xff1f; 方法 在Canvas子物体组件中勾选“光线透射目标”时&…

Python基础合集 练习17(类与对象)

class Dog: pass papiDog() print(papi) print(type(papi)) 构建方法 创建类过后可以定义一个特殊的方法。在python中构建方法是__init__(),init()必须包含一个self参数 class pig(): #def__init__(self) -> None&#xff1a; print(‘你好’) pipgpig() 属性和方法 cl…

C++好难(2):类和对象(上篇)

okay&#xff0c;从这里开始&#xff0c;就进入c比较难的部分了~啊啊啊&#xff01;&#xff01;&#xff01; (﹃ԅ) 坚持坚持啦 ~ ᵎ(•̀㉨•́)و ̑̑ 【本章目标】 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实…

(1)QT基础铺垫

目录 1.Qt特性 2. 新建项目 3. 工作目录与构建目录 4. 工作目录 4.1 .pro 项目配置文件 4.2 dialog.h 4.3 dialog.cpp 4.4 main.cpp 5. 帮助文档 6. 调试信息 1.Qt特性 Qt经常被当作是一个基于c语言的gui开发框架&#xff0c;但是这并不是qt的全部&#xff0c;除了开…

JavaWeb( 二 ) URL

1.4.URL统一资源定位符 URL代表Uniform Resource Locator 统一资源定位符&#xff0c;也叫 URL地址 。是用于标识和定位Web上资源的地址&#xff0c;通常用于在Web浏览器中访问网站和文件。 URL由若干部分组成&#xff0c;scheme:// host : port / path 例如&#xff1a; htt…

WxGL应用实例:绘制点云

WxGL附带了几个工具函数&#xff0c;其中read_pcfile用来解析.ply和.pcd格式的点云文件&#xff0c;该函数返回一个PointCloudData类实例&#xff0c;包含以下属性&#xff1a; PointCloudData.ok - 数据是否可用&#xff0c;布尔型PointCloudData.info - 数据可用性说明&…

《通过十几轮数据进行模型训练,实现精确的无创血糖测量的演绎学习》阅读笔记

目录 0 演绎学习 1 论文摘要 2 论文十问 3 论文亮点与不足之处 4 与其他研究的比较 5 实际应用与影响 6 个人思考与启示 参考文献 0 演绎学习 在本文中&#xff0c;DL指的是Deduction Learning&#xff0c;即演绎学习方法。该方法是一种机器学习方法&#xff0c;通过使…

简单毛概刷题网页制作 3.0(拖欠近一年版)

原因是大概一年之前学校的毛概期末刷题网站突然崩了&#xff0c;但是一直没有修复。当时眼看着复习时间逐渐被压缩&#xff0c;自己啥也做不了&#xff0c;遂自学前端完成毛概刷题网页一枚。 最早的毛概刷题网站仅仅是 1.0 版本&#xff08;传送门&#xff09;&#xff0c;功能…

STM32F4_USMART调试组件

目录 1. USMART是什么&#xff1f; 2. USMART的特点 3. USMART实现流程 4. USMART组件 5. 在usmart_config.c中添加想要被USMART调用的函数 6. 实验程序 6.1 main.c 6.2 usmart.c 6.3 usmart.h 7. USMART调试的优越性说明 1. USMART是什么&#xff1f; USMART 是 AL…

org.apache.poi 设置 Excel 单元格颜色 RGB

一、背景说明 在使用 org.apache.poi 导出 Excel 时&#xff0c;需要设置部分单元格的颜色。 可以使用方法&#xff1a;org.apache.poi.ss.usermodel.CellStyle.setFillForegroundColor() 和 org.apache.poi.ss.usermodel.CellStyle.setFillPattern() 来设置单元格的颜色和填…

低频量化之 可转债 配债数据及策略 - 全网独家

目录 历史文章可转债配债数据 待发转债&#xff08;进展统计&#xff09;待发转债&#xff08;行业统计&#xff09;待发转债&#xff08;5证监会通过&#xff0c;PE排序&#xff09;待发转债&#xff08;5证监会通过&#xff0c;安全垫排序&#xff09;待发转债&#xff08;5证…

【算法】一文彻底搞懂ZAB算法

文章目录 什么是ZAB 算法&#xff1f;深入ZAB算法1. 消息广播两阶段提交ZAB消息广播过程 2. 崩溃恢复选举参数选举流程 ZAB算法需要解决的两大问题1. 已经被处理的消息不能丢2. 被丢弃的消息不能再次出现 最近需要设计一个分布式系统&#xff0c;需要一个中间件来存储共享的信息…

Java 怎样实现代理模式,有什么优缺点

一、介绍 代理模式是一种常见的设计模式&#xff0c;它可以为其他对象提供一种代理以控制对这个对象的访问。代理对象具有与被代理对象相同的接口&#xff0c;客户端无需知道代理对象和被代理对象的区别。代理模式可以应用于各种不同的场景&#xff0c;例如远程代理、虚拟代理…

SpringBoot整合Mybatis-plus实现多级评论

在本文中&#xff0c;我们将介绍如何使用SpringBoot整合Mybatis-plus实现多级评论功能。同时&#xff0c;本文还将提供数据库的设计和详细的后端代码&#xff0c;前端界面使用Vue2。 数据库设计 本文的多级评论功能将采用MySQL数据库实现&#xff0c;下面是数据库的设计&…

vcruntime140.dll无法继续执行代码?vcruntime140.dll如何修复?只需要3步即可

vcruntime140.dll是用于Microsoft Visual C Redistributable&#xff08;可再发行组件&#xff09;的一部分&#xff0c;它是一个动态链接库文件&#xff0c;包含了该软件包提供的运行库。在许多应用程序和游戏中&#xff0c;vcruntime140.dll文件经常被使用。如果该文件缺失或…

spark 数据的加载和保存(Parquet、JSON、CSV、MySql)

spark数据的加载和保存 SparkSQL 默认读取和保存的文件格式为 parquet 1.加载数据 spark.read.load 是加载数据的通用方法 scala> spark.read. csv format jdbc json load option options orc parquet schema table text textFile 如果读取不同格式的数据&#xff0c;可以…
最新文章