力扣 21. 合并两个有序链表 C语言实现

news2024/11/30 2:36:58

题目描述:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

题目链接

方法1:遍历

新建一个链表 newList 用于存放合并后的链表,设置一个指针指向该链表最后一个位置的 next,分别判断两个链表当前位置的大小,将值小的元素插入 newList 的末尾,并向后移动当前链表的位置,直到两个链表中有一个链表为空。然后再依次查看哪个链表不为空,将不为空的链表剩下的元素插入 newList 中。

其中需要考虑的问题是应该如何向 newList 中插入元素。首先创建一个 newList 指针并指向空,同时创建一个指向newList末尾结点的指针 last,令 last=newList。

例如实例1,l1和l2初始时都指向头结点,判断头结点的元素大小,得到 l2的元素,确定元素后将该元素赋值给一个 cur 指针,由于当前 newList 指向为空,所以此时要让 newList=cur,并让last=newList,同时,也要让 l2 链表的当前位置向后移动,也就是 l2 = l2->next。保证每次last指向的都是newList的最后一个元素。当newList不为空时,将确定的元素赋给cur指针后,将newList末尾的指针的下一个指向cur,即 last->next=cur,然后再更新last的位置。让 last = last->next. 依次遍历,最后返回 newList。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode* newList=NULL;
    if(list1==NULL && list2==NULL)
    {
        return newList;
    }
    struct ListNode* last=newList;
    while(list1!=NULL && list2!=NULL)
    {

        if(list1->val < list2->val)
        {
            struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list1->val;
            cur->next = NULL;
            if(newList==NULL)
            {
                newList = cur;
                last = newList;
            }
            else
            {
                last->next = cur;
                last = last->next;
            }
            list1 = list1->next;
        }
        else
        {
            struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list2->val;
            cur->next = NULL;
            if(newList==NULL)
            {
                newList = cur;
                last = newList;
            }
            else
            {
                last->next = cur;
                last = last->next;
            }
            list2 = list2->next;
        }
    }
    while(list1!=NULL)
    {
        struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list1->val;
            cur->next = NULL;
            if(newList==NULL)
            {
                newList = cur;
                last = newList;
            }
            else
            {
                last->next = cur;
                last = last->next;
            }
            list1 = list1->next;
    }
    while(list2!=NULL)
    {
        struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list2->val;
            cur->next = NULL;
            if(newList==NULL)
            {
                newList = cur;
                last = newList;
            }
            else
            {
                last->next = cur;
                last = last->next;
            }
            list2 = list2->next;
    }
    return newList;
}

对于 newList 为空的情况,每次循环都需要进行判断较为麻烦,所以在 创建 newList 的时候,首先创建一个值为-1 的节点,令 last指向 newList,然后直接按照上述newList不为0的情况判断即可。遍历完两个链表并将值都赋给 newList后,返回值返回newList->next,跳过第一个元素。

改进后代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode* newList=(struct ListNode*)malloc(sizeof(struct ListNode));
    newList->val = -1;
    newList->next = NULL;
    if(list1==NULL && list2==NULL)
    {
        return newList->next;
    }
    struct ListNode* last=newList;
    while(list1!=NULL && list2!=NULL)
    {

        if(list1->val < list2->val)
        {
            struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list1->val;
            cur->next = NULL;
            last->next = cur;
            last = last->next;
            list1 = list1->next;
        }
        else
        {
            struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list2->val;
            cur->next = NULL;
            last->next = cur;
            last = last->next;
            list2 = list2->next;
        }
    }
    while(list1!=NULL)
    {
        struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list1->val;
            cur->next = NULL;
            last->next = cur;
            last = last->next;
            list1 = list1->next;
    }
    while(list2!=NULL)
    {
        struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
            cur->val = list2->val;
            cur->next = NULL;
            last->next = cur;
            last = last->next;
            list2 = list2->next;
    }
    return newList->next;
}

方法2:递归

使用递归不需要创建一个新的链表,直接在现有的两个链表中进行排序。 如下图,现在两个链表合并的函数是mergeTwoLists(L1, L2)

如上图,当前合并的链表应该为 L2->next = mergeTwoLists(L1, L2->next)

 对于这次,应该为L1->next = mergeTwoLists(L1->next, L2) 

递归的核心在于,只关注当前层要干什么,返回什么,至于我的下一层是不管的。

如果L1空,则返回L2,如果L2为空,则返回L1,这就是终止条件

如果L1第一个元素小于L2的, 那么就要把L1的这个元素放到最前面,至于后面的那串长啥样 ,不需要考虑. 我只要令当前的下一个节点等于下一层(令L1->next = 下一层)就行。

最终需要返回的就是当前节点加下一层。

代码如下 

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

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

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

相关文章

77.【JavaWeb文件上传和邮件发送04】

JavaWeb(二十五)、文件上传1.准备工作2.实用类介绍3.思维导图:4.正戏开始5.完整代码(二十六)、邮箱发送1.邮箱发送的原理:2.服务器的原理3.下载两个jar包4.基本类:5.全部代码(二十七)、网站注册发送邮件实现(二十五)、文件上传 1.首先创建一个empty项目 2.配置project项目中的…

【JVM】jvm中的栈简介

jvm中的栈简介一、JVM体系结构二、栈是什么&#xff1f;三、栈的特性四、栈帧五、栈的运行原理5.1 运行原理5.2 代码示例5.2.1 方法的入栈和出栈5.2.2 没有捕获异常5.2.3 捕获异常六、栈帧的内部结构七、运行时数据区&#xff0c;哪些部分存在Error和GC&#xff1f;八、本文源码…

boot 创建 https

需要在配置文件中&#xff1a;加入 server:ssl:key-store: classpath:https.keystorekey-store-type: JKSkey-alias: tomcatkey-password: 123456key-store-password: 123456port: 8089 这样原本请求的http&#xff0c;就需要变成https&#xff0c;其他类似 RestController p…

深度学习入门(五十六)循环神经网络——循环神经网络RNN

深度学习入门&#xff08;五十六&#xff09;循环神经网络——循环神经网络RNN前言循环神经网络——循环神经网络RNN课件潜变量自回归模型循环神经网络使用循环神经网络的语言模型困惑度&#xff08;perplexity&#xff09;梯度裁剪更多的应用RNNs总结教材1 无隐状态的神经网络…

周赛总结--LeetCode单周赛321场 AcWing79场

1. LeetCode单周赛321场 1.1 找出中枢整数 1.1.1 原题链接&#xff1a;力扣https://leetcode.cn/problems/find-the-pivot-integer/ 1.1.2 解题思路&#xff1a; 1、先保存 1-n 的和sum&#xff1b; 2、从 1 开始枚举&#xff0c;判断前 i 项和 cmp 与 sum - cmp i 是否相等…

MySQL第二弹

目录​​​​​​​ 一、数据库基本操作 1、查看数据库信息 2、查看数据库中的表信息 3、显示数据表的结构&#xff08;字段&#xff09; 4、常见的数据类型 4.1 数值类型 4.2 日期和时间类型 4.3 字符串类型 二、SQL语言概述 1、SQL语言 2、SQL分类 2.1 DDL:数据定…

【强化学习论文合集】NeurIPS-2021 强化学习论文

强化学习&#xff08;Reinforcement Learning, RL&#xff09;&#xff0c;又称再励学习、评价学习或增强学习&#xff0c;是机器学习的范式和方法论之一&#xff0c;用于描述和解决智能体&#xff08;agent&#xff09;在与环境的交互过程中通过学习策略以达成回报最大化或实现…

js——高阶函数、闭包、递归以及浅拷贝和深拷贝

目录 一、高阶函数 1、什么是高阶函数 2、把一个函数作为参数 3、return 返回的也是一个函数 二、闭包 1、闭包是什么 2、变量的作用域 3、案例 4、结果展示&#xff1a; 5、总结&#xff1a; 三、递归 1、什么是递归 2、案例一 3、分析 4、问题 5、栈溢出又是什…

【Unity Shader​】 屏幕后处理5.0:讨论双重模糊的Bloom

接上一篇基于高斯模糊的Bloom继续进行接下来的学习。 1 一些必要的思考* 1.1 关于高质量Bloom 前面提到了&#xff0c;Bloom对于游戏必不可少的效果之一&#xff0c;于是我们不仅仅要把Bloom效果实现出来&#xff0c;效果的质量好坏就更加是我们需要关注的点了。高质量泛光&a…

面试宝典之C++多态灵魂拷问

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、重载&#xff0c;隐藏/重定义&#xff0c;覆盖/重写二、多态的原理三、inline可以是虚函数吗四、静态成员函数可以是虚函数吗五、构造函…

海丝一号-中国-2020

2020年12月22日&#xff0c;由中国电科38所和天仪研究院联合研制的我国首颗商业SAR卫星“海丝一号”搭载长征八号运载火箭在文昌卫星发射中心成功发射。海丝一号历时一年完成研制&#xff0c;整星重量小于185kg&#xff0c;成像最高分辨率1m&#xff0c;可以全天时、全天候对陆…

章节5 文件与目录管理

5-Linux文件和目录管理 &#xff08;Linux操作系统-2022的前面章节都为铺垫&#xff09; 常见命令格式 Command Options Arguments 命令 选项 参数 rm -rf /* -一个字母或字母组合&#xff0c;此选项为短选项&#xff0c;–单词&#xff0c;此选项为长选项 Options选项&…

因果推断 | 双重差分法笔记补充

换了新的环境后&#xff0c;一直在适应&#xff08;其实是一直被推着走&#xff09;&#xff0c;所以停更了笔记好久啦。这一周周末终于有点得空&#xff0c;当然也是因为疫情&#xff0c;哪里都不能去&#xff0c;哈哈&#xff0c;所以来冒个泡~ 整理了最近pre的作业&#xf…

ESP32-CAM初始篇:Arduino环境搭建-->实现局域网推流

ESP32-CAM初始篇&#xff1a;Arduino环境搭建–>实现局域网推流 入手产品&#xff1a;安信可科技&#xff1a;ESP32-CAM摄像头开发板&#xff1a; 相关产品特性请访问安信可ESP32-CAM官网&#xff1a;https://docs.ai-thinker.com/esp32-cam 第一步&#xff1a;下载Ardui…

基于51单片机数字频率计的设计

目录 前 言 1 第一章 总体设计方案 2 1.1 总设计框图 2 1.2 硬件设计分析 2 1.2.1 电源的设计 2 &#xff08;4&#xff09;&#xff1a;LCD1602的指令说明及时序 10 &#xff08;5&#xff09;&#xff1a; LCD1602的RAM地址映射及标准字库表 13 第二章 软件设计与分析 15 2.1…

谷粒商城十一商城系统及整合thymeleaf渲染商城首页

我们的商城系统本应该也是前后端分离的&#xff0c;就像后台管理系统那样&#xff0c;然而出于教学考虑&#xff0c;前后端分离的话就会屏蔽掉很多细节&#xff0c;所以我们进行服务端的页面渲染式开发&#xff08;有点儿类似freemarker&#xff09; 这些页面直接粘贴到微服务…

含论文基于JSP的零食销售商城【数据库设计、源码、开题报告】

数据库脚本下载地址&#xff1a; https://download.csdn.net/download/itrjxxs_com/86500759 主要使用技术 ServletJSPcssjsMysqlTomcat 功能介绍 (1)前台功能模块&#xff1a; 注册登陆&#xff1a;顾客可以通过填写注册信息成为会员&#xff0c;登陆后才能进行购物车的管…

汽车 Automotive > SOME/IP应用学习

目录 SOME/IP介绍 SOME/IP主要功能 SOME/IP协议 SOME/IP服务类型 SOME/IP-举例 SOME/IP各模块协议 SOME/IP-基础元件 SOME/IP-SoAD SOME/IP-SD协议 SOME/IP-SD举例 SOME/IP-TP协议 SOME/IP-TP举例 SOME/IP介绍 SOME/IP ( Scalable service-Oriented Middleware ove…

基于Android的JavaEE课设

目录 1 技术栈 2 android前端 2.1 概述 2.1.1 目录结构 2.1.2 代码分层 2.2 技术点 2.2.1 数据绑定 2.2.2 前后端数据交互 2.2.3 九宫格图片 2.2.4 未处理消息提醒 2.2.5 动画效果 2.2.6 实时聊天 2.2.7 文件上传 2.2.8 底部弹窗 2.2.9 其他 3 后端 3.1 概述 …

BUUCTF Misc 假如给我三天光明 数据包中的线索 后门查杀 webshell后门

假如给我三天光明 下载文件&#xff0c;一个压缩包&#xff08;需要密码&#xff09;和图片 百度得知下面一行是盲文&#xff0c;根据盲文对照表 和上述图片对照&#xff0c;得到字符串&#xff1a;kmdonowg 。使用它解压压缩包 使用Audacity打开 转换成摩斯密码&#xff0c;…