算法刷题打卡第57天:合并两个有序链表

news2025/1/16 1:47:18

合并两个有序链表

难度:简单

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

示例 1:

在这里插入图片描述

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

示例 2:

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

示例 3:

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

解法一、递归

思路:

我们可以如下递归地定义两个链表里的 merge 操作(忽略边界情况,比如空链表等):

{ l i s t 1 [ 0 ] + m e r g e ( l i s t 1 [ 1 : ] , l i s t 2 ) l i s t 1 [ 0 ] < l i s t 2 [ 0 ] l i s t 2 [ 0 ] + m e r g e ( l i s t 1 , l i s t 2 [ 1 : ] ) o t h e r w i s e \left\{ \begin{array}{ll} list1[0] + merge(list1[1:], list2) & list1[0] < list2[0] \\ list2[0] + merge(list1, list2[1:]) & otherwise \end{array} \right. {list1[0]+merge(list1[1:],list2)list2[0]+merge(list1,list2[1:])list1[0]<list2[0]otherwise

也就是说,两个链表头部值较小的一个节点与剩下元素的 merge 操作结果合并。

我们直接将以上递归过程建模,同时需要考虑边界情况。

如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。

时间复杂度: O ( n + m ) O(n + m) O(n+m),其中 n n n m m m 分别为两个链表的长度。因为每次调用递归都会去掉 l 1 l1 l1 或者 l 2 l2 l2 的头节点(直到至少有一个链表为空),函数 m e r g e T w o L i s t mergeTwoList mergeTwoList 至多只会递归调用每个节点一次。因此,时间复杂度取决于合并后的链表长度,即 O ( n + m ) O(n+m) O(n+m)
空间复杂度: O ( n + m ) O(n+m) O(n+m),其中 n n n m m m 分别为两个链表的长度。递归调用 m e r g e T w o L i s t s mergeTwoLists mergeTwoLists 函数时需要消耗栈空间,栈空间的大小取决于递归调用的深度。结束递归调用时 m e r g e T w o L i s t s mergeTwoLists mergeTwoLists 函数最多调用 n + m n+m n+m 次,因此空间复杂度为 O ( n + m ) O(n+m) O(n+m)

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        if list1 is None:
            return list2
        if list2 is None:
            return list1
        if list1.val < list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        list2.next = self.mergeTwoLists(list1, list2.next)
        return list2

解法二、迭代

思路:

我们可以用迭代的方法来实现上述算法。当 l 1 l1 l1 l 2 l2 l2 都不是空链表时,判断 l 1 l1 l1 l 2 l2 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。

首先,我们设定一个哨兵节点 r e s res res,这可以在最后让我们比较容易地返回合并后的链表。我们维护一个 n o d e node node 指针,我们需要做的是调整它的 n e x t next next 指针。然后,我们重复以下过程,直到 l 1 l1 l1 或者 l 2 l2 l2 指向了 n u l l null null:如果 l 1 l1 l1 当前节点的值小于等于 l 2 l2 l2 ,我们就把 l 1 l1 l1 当前的节点接在 n o d e node node 节点的后面同时将 l 1 l1 l1 指针往后移一位。否则,我们对 l 2 l2 l2 做同样的操作。不管我们将哪一个元素接在了后面,我们都需要把 n o d e node node 向后移一位。

在循环终止的时候, l 1 l1 l1 l 2 l2 l2 至多有一个是非空的。由于输入的两个链表都是有序的,所以不管哪个链表是非空的,它包含的所有元素都比前面已经合并链表中的所有元素都要大。这意味着我们只需要简单地将非空链表接在合并链表的后面,并返回合并链表即可。

时间复杂度: O ( n + m ) O(n+m) O(n+m),其中 n n n m m m 分别为两个链表的长度。因为每次循环迭代中, l 1 l1 l1 l 2 l2 l2 只有一个元素会被放进合并链表中, 因此 w h i l e while while 循环的次数不会超过两个链表的长度之和。所有其他操作的时间复杂度都是常数级别的,因此总的时间复杂度为 O ( n + m ) O(n+m) O(n+m)

空间复杂度: O ( 1 ) O(1) O(1)。我们只需要常数的空间存放若干变量。

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        res = ListNode()
        node = res
        while list1 and list2:
            if list1.val < list2.val:
                node.next = list1
                list1 = list1.next
            else:
                node.next = list2
                list2 = list2.next
            node = node.next
        if list1:
            node.next = list1
        if list2:
            node.next = list2
        return res.next

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-two-sorted-lists

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

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

相关文章

liunx中搭建python3.7环境和安装pycharm并搭建Django

首先第一步我们先安装python3.7的环境在liunx中&#xff0c;先去下面这个网站然后找到Gzipped source tarball https://www.python.org/downloads/release/python-377/ 下拉到最底下选择它然后下载 如果python中已经安装就跳过这一步 用python --version 检查后如果已经装好pyt…

【2022年终总结】期待下一个365天

2022结束啦&#xff01;&#xff01;&#xff01;日出万物生&#xff0c;日落满天星&#xff0c;期待下一个365天&#xff01;&#xff01;&#xff01; 不知不觉在CSDN断断续续写文章已经四个月了&#xff0c;回想这段日子&#xff0c;还是很有必要纪念一下的&#xff0c;本期…

ArcGIS基础实验操作100例--实验61数据框投影变换

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验61 数据框投影变换 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&am…

JavaScript 模块化 —— 从概念到原理

走过路过发现 bug 请指出&#xff0c;拯救一个辣鸡&#xff08;但很帅&#xff09;的少年就靠您啦&#xff01;&#xff01;&#xff01; 1. 为什么需要 Javascipt 模块化&#xff1f; 1.解决命名冲突。将所有变量都挂载在到全局 global 会引用命名冲突的问题。模块化可以把变…

人工智能与python

人工智能的话题在近几年可谓是相当火热&#xff0c;前几天看快本时其中有一个环节就是关于人工智能的&#xff0c;智能家电、智能机器人、智能工具等等&#xff0c;在我的印象里&#xff0c;提到人工智能就会出现 Python&#xff0c;然后我便在网上查找了相关信息&#xff0c;并…

(第三章)OpenGL超级宝典学习:认识渲染管线

OpGL超级宝典学习&#xff1a;认识渲染管线 前言 本章作为OpenGL学习的第三章节 在本章节我们将认识OpenGL的渲染管线 对管线内各个过程有一个初步的认识 ★提高阅读体验★ &#x1f449; ♠一级标题 &#x1f448; &#x1f449; ♥二级标题 &#x1f448; &#x1…

【KG】TransE 及其实现

原文&#xff1a;https://yubincloud.github.io/notebook/pages/paper/kg/TransE/ TransE 及其实现 1. What is TransE? TransE (Translating Embedding), an energy-based model for learning low-dimensional embeddings of entities. 核心思想&#xff1a;将 relationship …

基于R的Bilibili视频数据建模及分析——建模-因子分析篇

基于R的Bilibili视频数据建模及分析——建模-因子分析篇 文章目录基于R的Bilibili视频数据建模及分析——建模-因子分析篇0、写在前面1、数据分析1.1 建模-因子分析1.2 对数线性模型1.3 主成分分析1.4 因子分析1.5 多维标度法2、参考资料0、写在前面 实验环境 Python版本&#…

防火墙命令

启动&#xff1a; systemctl start firewalld 查看状态&#xff1a; systemctl status firewalld 停止&#xff1a;systemctl stop firewalld 禁用&#xff1a;systemctl disable firewalld 怎么开启一个端口呢 添加 firewall-cmd --zonepublic --add-port80/tcp --permanent …

easyx保姆级教程---->从游戏玩家到游戏制作者

请点击这里&#xff1a;安装教程 1.头文件 #include<easyx.h> //这个是只包含最新的API(函数接口) #include<graphics.h> //这个头文件包含了上面的&#xff0c;还包含了已经不推荐使用的函数2.窗口 1.初始化绘制窗口 initgraph(width,height,flag); //窗…

Domino Web应用中的搜索功能和结果选择问题

大家好&#xff0c;才是真的好。 还有不到十天Domino多瑙河版本就将发布&#xff0c;在此之前&#xff0c;我们还是讲述一下Web中的搜索技术。 废话不多说&#xff0c;我们直接上干货。 Notes应用的视图在Web浏览器中可以直接展现&#xff0c;并且可选择。 如果这样展现的话…

【QGIS入门实战精品教程】8.1:QGIS制作地图案例教程

文章目录 一、加载矢量数据二、加载影像底图三、美化矢量数据四、切换到排版视图五、添加经纬度格网六、添加其他修饰元素七、地图输出一、加载矢量数据 加载本实验数据基础数据.gpkg中的甘肃省政区矢量数据,如下所示: 二、加载影像底图 QGIS加载在线地图案例教程参考: 【…

5、Java中的JDBCJDBCUtilsJDBC控制事务getResource中文或有空格路径处理ResourceBundle演示

JDBC&#xff1a; 1. 概念&#xff1a;Java DataBase Connectivity Java 数据库连接&#xff0c; Java语言操作数据库 * JDBC本质&#xff1a;其实是官方&#xff08;sun公司&#xff09;定义的一套操作所有关系型数据库的规则&#xff0c;即接口。各个数据库厂商去实现这…

回收租赁商城系统功能拆解04讲-商品品牌

回收租赁系统适用于物品回收、物品租赁、二手买卖交易等三大场景。 可以快速帮助企业搭建类似闲鱼回收/爱回收/爱租机/人人租等回收租赁商城。 回收租赁系统支持智能评估回收价格&#xff0c;后台调整最终回收价&#xff0c;用户同意回收后系统即刻放款&#xff0c;用户微信零…

第04章 程序控制结构

在程序中&#xff0c;程序运行的流程控制决定程序是如何执行的。 顺序控制 介绍&#xff1a; 程序从上到下的逐行的执行&#xff0c;中间没有任何判断和跳转。 使用&#xff1a;java中定义变量时&#xff0c;采用合法的前向引用。如&#xff1a; public class Test{int num…

【虚幻引擎】UE4/UE5像素流在广域网上(云)部署(多实例)

一、选择云服务器 每个云平台都提供许多预设的镜像选择&#xff0c;由于像素流技术目前只支持Windows操作系统&#xff0c;所以我们需要选择Windows Server的镜像&#xff0c;2012/2016/2019皆可。我们这里选择了Windows Server 2016 R2 简体中文版的镜像&#xff0c;之所以选择…

【SSM整合】对Spring、SpringMVC、MyBatis的整合,以及Bootstrap的使用,简单的新闻管理系统

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Spring】 &#x1f96d;本文内…

代码随想录第53天|● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

1143.最长公共子序列 和718.最长重复子数组类似 包括二维数组初始化这些 不同之处在于递推公式主要就是两大情况&#xff1a; text1[i - 1] 与 text2[j - 1]相同&#xff0c;text1[i - 1] 与 text2[j - 1]不相同 如果text1[i - 1] 与 text2[j - 1]相同&#xff0c;那么找到了…

Windows/Linux日志分析

Windows日志分析 Windows系统日志是记录系统中硬件、软件和系统问题的信息&#xff0c;同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因&#xff0c;或者寻找受到攻击时攻击者留下的痕迹。 Windows主要有以下三类日志记录系统事件&#xff1a;应用程序日志…

【链表】leetcode707.设计链表(C/C++/Java/Js)

leetcode707.设计链表1 题目2 思路3 代码3.1 C版本3.2 C版本3.3 Java版本3.3.1 单链表3.3.2 双链表3.4 JavaScript版本4 总结1 题目 题源链接 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性&#xff1a;val 和 next。val 是当前节点的值&…