链上的羁绊,数据与节点的暗涌心跳

在这里插入图片描述

公主请阅

  • 1. 合并两个有序链表
    • 1.1 题目说明
      • 示例 1
      • 示例 2
      • 示例 3
    • 1.2 题目分析
    • 1.3 代码部分
    • 1.4 代码分析
  • 2. 链表的中间节点
    • 2.1 题目说明
      • 示例 1
      • 示例 2
    • 2.2 题目分析
    • 2.3 代码部分
    • 2.4 代码分析

1. 合并两个有序链表

在这里插入图片描述

题目传送门


1.1 题目说明

这个问题要求将两个升序链表合并成一个新的升序链表。新的链表是通过按顺序连接两个输入链表的所有节点组成的。

  1. 输入:两个链表,且这两个链表都是升序的。
  2. 输出:一个包含所有输入链表元素的升序链表。

示例 1

  • 输入:l1 = [1, 2, 4], l2 = [1, 3, 4]
  • 输出:[1, 1, 2, 3, 4, 4]

示例 2

  • 输入:l1 = [], l2 = []
  • 输出:[]

示例 3

  • 输入:l1 = [], l2 = [0]
  • 输出:[0]

这个问题的主要任务是遍历两个链表,按大小顺序逐个节点合并,形成一个新的升序链表。


1.2 题目分析

将两个链表合成为一个链表并且将表头返回,那么我们应该怎么做呢?
对于这个题我们可以先将特殊情况进行处理,如果其中一个链表是空的,那么我们将剩下的那个进行返回操作就行了

解决完特殊情况后我们就进行这道的思路讲解了

我们可以对两个链表进行遍历的操作,然后比较对应的节点的大小,在此之前我们先创建一个哨兵位用来占位子,如果哪个节点大的话我们就让哨兵位的nxet指向指向谁
然后我们就一次进行遍历,这个相当于在两个链表的基础上创建了一个新链表,在判断完大小之后,我们遍历两个链表的指针往后走,我们的哨兵位的指针也往后走
等循环结束之后,我们肯定是有一个链表处理完了,但是还有一个链表还有剩余的节点的
如果哪个链表还是剩余的节点,我们直接让在哨兵位开始遍历的指针进行next指针的指向操作就行了,将剩余的节点接在后面就行了
最后,因为我们的哨兵位是一个空壳,我们返回的是哨兵位的下个节点,这个节点才是名副其实的头结点


1.3 代码部分

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

 /*
 先把特殊情况归类出来,然后我们再进行题目分析
 两个链表合并,我们是需要一个新的链表进行数据的存储的
 逐个对l1和l2的节点内的数据大小进行比较,通过while循环,那么结束条件是什么呢?


 */
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    //特殊情况下
    if(list1==NULL)
    {
        return list2;
    }
    else if(list2==NULL)
    {
        return list1;
    }

    ListNode *ps=(ListNode*)malloc(sizeof(ListNode));//创建一个伪头节点
    ListNode*tmp=ps;

    while(list1!=NULL&&list2!=NULL)
    {
        if(list1->val<=list2->val)//l1节点的值小于等于l2节点的值
        {
            tmp->next=list1;//那么list1就是这个伪节点的下一个节点
            list1=list1->next;//换下一个节点
        }
        else
        {
            tmp->next=list2;
            list2=list2->next;
        }
        tmp=tmp->next;//伪节点往后走
    }
    //到这里要么两个链表都处理完了,要么就是还剩下一个链表
    if(list1!=NULL)
    {
        tmp->next=list1;
    }
    if(list2!=NULL)
    {
        tmp->next=list2;
    }
    return ps->next;//因为ps是个伪节点,不存储真实的数据
}

1.4 代码分析

我们先将特殊情况进行处理了
处理完成之后我们先动态申请一个伪头结点ps
然后我们创建一个指针tmp指向这个头结点
然后我们可以开始进行循环遍历两个链表同时进行判断操作了
我们使用while循环,循环结束的条件就是两个链表的指针都不能是空,就是说我们的链表到尾节点就停下来
在循环中我们进行两个指针对应节点的判断,如果哪个节点对应的值小的话,我们就让我们的tmp指针的next指向这个节点
然后我们被指向的节点指向完成之后,上面的指针就往后进行遍历继续比较大小
然后在一轮比较结束之后,我们的tmp也需要往后面走一步进行遍历操作
然后出了循环,我们的两个链表要么都处理完了,要么就是存在一个链表有剩余的节点
我们直接让tmp指向剩余链表的节点了
最后我们返回这个哨兵位的的下个节点,这个节点就是有效的节点了


2. 链表的中间节点

在这里插入图片描述
题目传送门


2.1 题目说明

给你单链表的头结点 head,请你找出并返回链表的中间结点。

  • 如果有两个中间结点,则返回第二个中间结点。

示例 1

  • 输入:head = [1,2,3,4,5]
  • 输出:[3,4,5]
  • 解释:链表只有一个中间结点,值为 3

示例 2

  • 输入:head = [1,2,3,4,5,6]
  • 输出:[4,5,6]
  • 解释:该链表有两个中间结点,值分别为 34,返回第二个结点。

2.2 题目分析

我们需要求出这个链表的中间节点,那么我们应该怎么实现呢?
我们是可以利用快慢指针进行这个效果的实现的
我们让慢指针走一步,快指针走两步
然后我们快指针到尾节点的时候,我们慢指针刚好在中间的位置
那么这个时候我们直接将慢指针进行返回的操作就行了


2.3 代码部分

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head)
{
    //利用快慢指针
    ListNode*slow=head;
    ListNode*fast=head;
    
    while(fast!=NULL&&fast->next!=NULL)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;

}

2.4 代码分析

我们创建了两个指针

  • slow慢指针—走一步每次
  • fast快指针----走两步每次

利用好数学规律,我们就将这个题解决了
我们利用while循环进行链表的遍历操作
循环条件就是fast!=NULL&&fast->next!=NULL

那么这个条件能不能换过来呢?
在你的快慢指针算法中,循环条件 while (fast != NULL && fast->next != NULL) 是确保快指针能安全地前进。我们来讨论如果将条件顺序换成 while (fast->next != NULL && fast != NULL) 会发生什么。

原始条件分析:

while (fast != NULL && fast->next != NULL)

这里的顺序先检查 fast != NULL,再检查 fast->next != NULL。这样做的原因是:

  • 先检查 fast != NULL 可以确保在访问 fast->next 之前,fast 指针是有效的(即不为 NULL)。
  • 如果先检查 fast->next != NULLfast 本身已经是 NULL,就会导致程序崩溃,因为 NULL->next 是非法操作。
    如果换成 fast->next != NULL && fast != NULL
while (fast->next != NULL && fast != NULL)

在这种情况下,编译器首先会检查 fast->next != NULL,但是如果 fast 本身是 NULL,就会试图访问 NULL->next,导致未定义行为或者程序崩溃。

为什么不能换过来?
如果 fastNULL,则它没有任何成员可以访问,包括 next。因此,必须首先检查 fast 是否是 NULL。否则,会出现对空指针的非法访问,导致运行时错误。

结论
条件 不能换过来。必须先检查 fast != NULL,确保 fast 不是空指针,然后再检查 fast->next

然后我们快指针走一步,慢指针走两步,等到循环结束之后,慢指针就在中间节点上,我们将slow指针进行返回就行了

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

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

相关文章

安装谷歌JSON可视化插件-JSON-Handle

背景&#xff1a; 最近在学习node开发&#xff0c;返回的数据看起来太难受&#xff0c;非常需要浏览器自动格式化接口返回的json数据。以下介绍一下怎么在浏览器安装JSON-Handle插件。 步骤&#xff1a; 1、下载扩展文件 地址&#xff1a;JSON-Handle 官网 - 打开json格式文…

健康推荐系统:SpringBoot技术革新

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

音频分割:长语音音频 分割为 短语音音频 - python 实现

在做语音任务时&#xff0c;有是会用到的语音音频是长音频&#xff0c;这就需要我们将长音频分割为短音频。 该示例将声音的音量和静默时间结合作为语音的分割条件。 使用音量和静默时间结合的分割条件&#xff0c;能够比较好的进行自然断句&#xff0c;不会话语没有说完就切断…

Pycharm下载安装教程(详细步骤)+汉化设置教程

今天讲解的是Pycharm安装教程和配置汉化设置&#xff0c;希望能够帮助到大家。 创作不易&#xff0c;还请各位同学三连点赞&#xff01;&#xff01;收藏&#xff01;&#xff01;转发&#xff01;&#xff01;&#xff01; 对于刚入门学习Python还找不到方向的小伙伴可以试试…

搭建mongodb单机部署-认证使用

搭建mongodb单机部署-认证使用 实现思路 先将配置文件配置好&#xff0c;使用不用认证的启动命令启动docker&#xff0c;然后创建账号并制定角色。在使用开启认证的命令重新启动容器就好。 这里我并没有说先停止容器&#xff0c;删掉容器重新创建容器。是因为我的启动命令中…

MyBatis 用法详解

文章目录 一、普通 SQL1.1 注解实现&#xff1a;1.1.1 参数传递&#xff1a;1.1.2 增&#xff08;Insert&#xff09;&#xff1a;1.1.3 删&#xff08;Delete&#xff09;&#xff1a;1.1.4 改&#xff08;Update&#xff09;&#xff1a;1.1.5 查&#xff08;Select&#xff…

OpenCV高级图形用户界面(15)注册一个回调函数来处理鼠标事件的函数setMouseCallback()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 为指定的窗口设置鼠标处理器。 setMouseCallback 是 OpenCV 中的一个功能&#xff0c;允许开发者注册一个回调函数来处理鼠标事件。当用户在窗口…

自监督学习:引领机器学习的新革命

引言 自监督学习&#xff08;Self-Supervised Learning&#xff09;近年来在机器学习领域取得了显著进展&#xff0c;成为人工智能研究的热门话题。不同于传统的监督学习和无监督学习&#xff0c;自监督学习通过利用未标注数据生成标签&#xff0c;从而大幅降低对人工标注数据…

champ模型部署指南

一、介绍 champ是由阿里巴巴、复旦大学和南京大学的研究人员共同提出的一种基于3D的将人物图片转换为视频动画的模型&#xff0c;该方法结合了3D参数化模型(特别是SMPL模型)和潜在扩散模型&#xff0c;能够精确地捕捉和再现人体的3D形状和动态&#xff0c;同时保持动画的时间一…

用SVM做时间序列预测真绝!最新思路无敌了,卷不动的进来看!

时间序列预测算法如今也算是百花齐放了&#xff0c;不过最近大家都在卷爆火的Transformer-based&#xff0c;卷不动的盆友其实也可以考虑从传统方法下手找创新&#xff0c;比如用SVM做时间序列预测。 SVM是一种经典的机器学习算法&#xff0c;在处理非线性及高维模式识别方面很…

k8s中的微服务

一、什么是微服务 用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f;需要通过微服务暴漏出去后才能被访问 Service是一组提供相同服务的Pod对外开放的接口。 借助Service&#xff0c;应用可以实现服务发现和负载均衡。 service默认只支持4层负载均…

黑马程序员-redis项目实践笔记2

目录 三、 Redis实现全局唯一ID 实现优惠卷秒杀下单 超卖问题 一人一单&#xff08;单例项目线程安全问题&#xff09; 一人一单&#xff08;集群环境下的并发问题&#xff09; 分布式锁的基本原理和实现方式对比 Redis分布式锁 实现核心思路 实现代码 Redis分布式锁…

供应商管理是什么?

你是一家制造业的老板&#xff0c;在需求旺盛的时段&#xff0c;却找不到一家合适的供应商&#xff0c;出现供应商突然退出合作&#xff1b;杀熟&#xff0c;供应的产品质量不过关等情况&#xff0c;企业的利益空间瞬间被压榨&#xff0c;急需一套管理系统来帮助选择供应商&…

《七度荒域:混沌之树》风灵月影二十二项游戏辅助:上帝模式/无限HP和EP/金币不减

《七度荒域:混沌之树》是款国产Roguelike银河恶魔城横版动作游戏&#xff0c;融合刷宝玩法。玩家将扮演修补世界的命运之子&#xff0c;探寻碎裂世界的秘密&#xff0c;在战斗轮回中成长&#xff0c;挑战未知与隐秘力量。风灵月影版修改器提供更多自定义和游戏体验调整选项&…

关于MyBatis的一些面试题

mybatis的执行流程 MyBatis 的执行流程主要包括 SQL 解析、参数绑定、执行查询/更新、结果映射等几个步骤。下面详细解释每个步骤的执行流程&#xff1a; 1. 加载配置文件和映射文件 加载 MyBatis 配置文件&#xff1a;启动时&#xff0c;MyBatis 通过 SqlSessionFactoryBui…

Transformer图解以及相关的概念

前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架&#xff0c;同时大部分LLM也是使用其进行训练生成模型&#xff0c;所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面…

2018年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;TCP/IP体系结构应用层常用协议及其相应的运输层协议 TCP协议是面向连接可靠数据传输服务&#xff0c;UDP无连接不可靠的数据传输服务&#xff0c;IP无连接不可靠的数据连接服务。 FTP协议&#xff0c;SMTP协议和HTTP协议使用TCP协议提供的面…

SaaS架构:中央库存系统架构设计

大家好&#xff0c;我是汤师爷~ 近年来&#xff0c;越来越多的零售企业大力发展全渠道业务。在销售额增长上&#xff0c;通过线上的小程序、直播、平台渠道等方式&#xff0c;拓展流量变现渠道。在会员增长方面&#xff0c;通过多样的互动方式&#xff0c;全渠道触达消费者&am…

Power BI - 设置Waterfall Chart第一个Pillar的颜色

1.简单介绍 有的用户可能会单独设置Column Chart&#xff08;条形图&#xff09;的第一个柱子的颜色&#xff0c;如下图所示&#xff0c; 这种其实可以通过Column Chart的Conditional formating进行设置&#xff0c; - SWICH SELECTEDVALUE 或者也可以直接对单独的Column进行…

深入拆解TomcatJetty(一)

深入拆解Tomcat&Jetty&#xff08;一&#xff09; 专栏地址&#xff1a;https://time.geekbang.org/column/intro/100027701 1、Web容器是什么 早期的 Web 应用主要用于浏览新闻等静态页面&#xff0c;HTTP 服务器&#xff08;比如 Apache、Nginx&#xff09;向浏览器返…