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

在这里插入图片描述

公主请阅

  • 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指针进行返回就行了

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

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

相关文章

Chinese Fineweb Edu v2即将开源

Chinese Fineweb Edu&#x1f517;&#xff1a;https://opencsg.com/datasets/OpenCSG/chinese-fineweb-edu huggingface&#x1f517;&#xff1a;https://huggingface.co/opencsg

LeetCode 3319. 第 K 大的完美二叉子树的大小

LeetCode 3319. 第 K 大的完美二叉子树的大小 给你一棵 二叉树 的根节点 root 和一个整数k。 返回第 k 大的 完美二叉子树的大小&#xff0c;如果不存在则返回 -1。 完美二叉树 是指所有叶子节点都在同一层级的树&#xff0c;且每个父节点恰有两个子节点。 子树 是指树中的某一…

【4.10】图搜索算法-BFS和DFS解电话号码的字母组合

一、题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits "23" 输出…

CEEMDAN +组合预测模型(BiLSTM-Attention + ARIMA)

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现&#xff08;一&#xff09;EMD-CSDN博客 EMD、EEM…

【高阶数据结构】揭开红黑树‘恶魔’的面具:深度解析底层逻辑

高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;二叉搜索树AVL树 大家好&#xff0c;我是店小二&#xff0c;欢迎来到本篇内容&#xff01;今天我们将一起探索红黑树的工作原理及部分功能实现。红黑树的概念相对抽象&#xff0c;但只要我们一步步深入…

flutter assets配置加载本地图片报错

首选列出我在照着网上说的设置assets怎么搞都报错&#xff0c;错误如下&#xff0c;搞的我想骂娘。 flutter: uses-material-design: true assets: - assets/images 后来找到了下面这个教程&#xff0c;才终于解决&#xff0c;就是要在后面加一个"/" 。 flutter这个…

【分布式知识】MapReduce详细介绍

文章目录 MapReduce概述1. MapReduce编程模型Map阶段Reduce阶段 2. Shuffle和Sort阶段3. MapReduce作业的执行流程4. MapReduce的优化和特性5. MapReduce的配置和调优 MapReduce局限性相关文献 MapReduce概述 MapReduce是一个分布式计算框架&#xff0c;它允许用户编写可以在大…

【热门】智慧果园管理系统解决方案

随着科技的进步,原有农业种植方式已经不能满足社会发展的需要,必须对传统的农业进行技术更新和改造。经过多年的实践,人们总结出一种新的种植方法——温室农业,即“用人工设施控制环境因素,使作物获得最适宜的生长条件,从而延长生产季节,获得最佳的产出”。这种农业生产方式…

scala 类的继承

继承的定义 idea实例 语法 重写 重写&#xff1a;在子类中重新定义父类的同名方法 idea实例 多态 多态&#xff1a;传入的对象不同&#xff0c;调用的方法的效果就不同&#xff01; 原理&#xff1a;参数是父类类型 idea实例 构造器

使用开源的 Vue 移动端表单设计器创建表单

FcDesigner Vant 版是一款基于 Vue3.0 的移动端低代码可视化表单设计器工具&#xff0c;通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单&#xff0c;提高开发者对表单的开发效率&#xff0c;节省开发者的时间。 源码下载 | 演示地址 | 帮助文档 本项目采用 Vue3.0 和 …

3D医学影像开发入门<二>:VS2019+Qt5.15.2+VTK9.3.1编译及环境配置

VTK&#xff08;Visualization Toolkit&#xff09;是一个开源的、跨平台的三维可视化开发库&#xff0c;用于处理和可视化三维数据。它提供了一系列算法和工具&#xff0c;用于创建、操作和渲染复杂的三维图形&#xff0c;并支持多种数据表示方式&#xff0c;包括点、线、面、…

Spring Boot知识管理系统:用户体验设计

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

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

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

部署私有仓库以及docker web ui应用

官方地址&#xff1a;https://hub.docker.com/_/registry/tags 一、拉取registry私有仓库镜像 docker pull registry:latest 二、运⾏容器 docker run -itd -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry1" --restartalways -p 5000:5000 …

Android取证简介(翻译)

在此文中&#xff0c;我们将探讨 Android 取证、获取 Android 设备的过程、反取证技术以及从 Android 设备映像分析和恢复已删除文件的实际示例。 # 本文中使用的关键术语 采集(Acquisition) &#xff1a; 在数字取证调查期间收集敏感数据 取证健全性(Forensically Soundnes…

【linux】Microsoft Edge 的 Bookmarks 文件存储位置

在 Linux 系统中&#xff0c;Microsoft Edge 的书签&#xff08;Bookmarks&#xff09;文件存储在用户的配置目录下。具体路径通常如下&#xff1a; ~/.config/microsoft-edge/Default/Bookmarks说明&#xff1a; 路径解释&#xff1a; ~ 表示当前用户的主目录。.config 是一个…

pinia学习笔记(1.0)

首先贴出官网地址&#xff1a;开始 | Pinia pinia作为Vue3项目中常用的状态管理工具&#xff0c;正逐渐取代vuex&#xff0c;现从0到1自己搭建pinia仓库。 首先&#xff0c;安装pinia&#xff0c;使用包管理器工具&#xff08;npm,pnpm,yarn,Bun等都可以&#xff09; 安装成…

UE5运行时动态加载场景角色动画任意搭配-相机及运镜(二)

通过《MMD模型及动作一键完美导入UE5》系列文章,我们可以把外部场景、角色、动画资产导入UE5,接下来我们将实现运行时动态加载这些资产,并任意组合搭配。 1、运行时播放相机动画 1、创建1个BlueprintActor,通过这个蓝图动态创建1个LevelSequence,并Play 2、将这个Bluep…

linux基本环境配置 安装Docker RedisMysql

目录 一、安装docker 1、卸载系统之前的docker 2、安装Docker-CE 3、启动docker 4、设置docker开机自启 5、root测试docker命令 6、配置docker镜像加速 二、Docker安装Mysql 1、下载镜像文件 2、创建实例并启动 3、修改MySQL字符集 4、设置容器自启动 三、Docker安…

CTFHUB技能树之SQL——MySQL结构

开启靶场&#xff0c;打开链接&#xff1a; 先判断一下是哪种类型的SQL注入&#xff1a; 1 and 11# 正常回显 1 and 12# 回显错误&#xff0c;说明是整数型注入 判断一下字段数&#xff1a; 1 order by 2# 正常回显 1 order by 3# 回显错误&#xff0c;说明字段数是2列 知道…