【面试经典150 | 链表】合并两个有序链表

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:递归
    • 方法二:迭代
  • 写在最后

Tag

【递归】【迭代】【链表】


题目来源

21. 合并两个有序链表


题目解读

合并两个有序链表。


解题思路

一种朴素的想法是将两个链表中的值存入到数组中,然后对数组进行升序排序,最后将排序好的数组还原回链表,这是一种可行的思路,但是没有充分利用题目已知的两个链表有序的条件,大家可以自行尝试,练习基础语法与建立链表节点的知识。

方法一:递归

我们记两个链表的头节点分别为 l1l2,在合并两个链表的时候会遇到以下三种情况:

  • l1 为空,直接返回 l2
  • l2 为空,直接返回 l1;
  • 两节点都不为空,那么又会分为两种情况:
    • l1 节点值小于 l2 节点值,那么 l1 节点将会是合并后的节点新的头节点,剩下的部分是 l1->nextl2 合并的节点,而合并 l1->nextl2 是合并 l1l2 的子问题,也可以使用 mergeTwoLists 函数来解答,于是有 l1->next = mergeTwoLists(l1->next, l2),并返回 l1
    • 同理,l2 节点值小于 l1 节点值时,有 l2->next = mergeTwoLists(l1, l2->next),并返回 l1
  • 以上这种将问题转换为原问题的子问题的方法,称为递归方法。递归方法是一种边调用边填充的方法。

实现代码

C++

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {if (list1 == nullptr) {return list2;}else if (list2 == nullptr) {return list1;}else if (list1->val < list2->val) {list1->next = mergeTwoLists(list1->next, list2);return list1;}else {list2->next = mergeTwoLists(list1, list2->next);return list2;}} 
};

python3

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def mergeTwoLists(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:if l1 is None:return l2elif l2 is None:return l1elif l1.val < l2.val:l1.next = self.mergeTwoLists(l1.next,l2)return l1else:l2.next = self.mergeTwoLists(l1, l2.next)return l2        

复杂度分析

时间复杂度: O ( m + n ) O(m+n) O(m+n) m m m n n n 分别为两个链表的长度,每个节点都是被递归调用一次。

空间复杂度: O ( m + n ) O(m+n) O(m+n),每调用一次函数 mergeTwoLists 都需要消耗栈空间,栈空间的大小取决于递归调用的深度。

方法二:迭代

迭代的方法是一种相对容易理解的方法。为了方便实现,我们定义一个哑节点 dummyListNode* dummy = new ListNode(-1);,最后只需要返回 dummy->next

我们再定义一个节点 prev 用来指向当前值较小的节点,初始 prev = dummy,我们迭代枚举两链表中的节点:

  • prev 指向值较小的节点;
  • 值较小的节点更新为下一个节点,方便下一对节点的比较;
  • prev 更新为下一个节点,为存放下一个更小的节点做准备;
  • 如果有一个链表为空了,直接退出迭代循环;
  • 需要注意这时候,两个链表中可能还有一个链表非空,需要将剩下的非空部分接在 prev 后面。

以上就是本题的迭代方法。

实现代码

C++

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {ListNode* dummy = new ListNode(-1);ListNode* prev = dummy;while(list1 && list2){if(list1->val < list2->val){prev->next = list1;list1 = list1->next;}else{prev->next = list2;list2 = list2->next;}prev = prev->next;}prev->next = list1 ? list1 : list2;return dummy->next;}
};

python3

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def mergeTwoLists(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:dummy = ListNode(-1)prev = dummywhile l1 and l2:if l1.val < l2.val:prev.next = l1l1 = l1.nextelse:prev.next = l2l2 = l2.nextprev = prev.nextprev.next = l1 if l1 is not None else l2return dummy.next

复杂度分析

时间复杂度: O ( m + n ) O(m+n) O(m+n) m m m n n n 分别为两个链表的长度,每个节点都是被递归调用一次。

空间复杂度: O ( 1 ) O(1) O(1)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

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

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

相关文章

HTTP发起请求与收到响应的大致过程

可以《《透视 HTTP 协议》Windows 10 搭建最小实验环境》搭建环境&#xff0c;之后才能进行下边的操作。 1.鼠标左键点击两下www目录下的start.bat批处理文件。 2.打开Wireshark&#xff0c;然后选择Adapter for loopback traffic capture。 3.然后把tcp.port 80 || udp.…

Linux--进程等待

1.什么是进程等待 1.通过系统调用wait/waitid,来对子进程进行进行检测和回收的功能。 2.为什么有进程等待 1.对于每个进程来说&#xff0c;如果子进程终止&#xff0c;父进程没有停止&#xff0c;就会形成僵尸进程&#xff0c;导致内存泄露&#xff0c;为了防止僵尸进程的形成…

win10 + VS2017 编译libjpeg(jpeg-9b)

需要用到的文件&#xff1a; jpeg-9b.zip win32.mak 下载链接链接&#xff1a;https://pan.baidu.com/s/1Z0fwbi74-ZSMjSej-0dV2A 提取码&#xff1a;huhu 步骤1&#xff1a;下载并解压jpeg-9b。 这里把jpeg-9b解压到文件夹"D:\build-libs\jpeg\build\jpeg-9b" …

如何使用 nvm-windows 这个工具来管理你电脑上的Node.js版本

nvm-windows 是一个用于管理在 Windows 上安装的多个 Node.js 版本的工具。以下是安装和使用 nvm-windows 的步骤&#xff1a; 第1步&#xff1a;下载 nvm-windows 访问 nvm-windows 的 GitHub发布页面.下载最新版本的 nvm-setup.zip 文件。 第2步&#xff1a;安装 nvm-wind…

uniapp 单选框以及多选框样式更改

radio以及checkbox默认样式不符合自身需求时&#xff0c;根据自身需求更改样式&#xff0c;以下是自身的示例&#xff1a; 单选&#xff1a; 多选&#xff1a; 由于uniapp自身包含了一套默认的样式&#xff0c;所以如果不想全局更改只想在某个单据页面使用的话&#xff0c;就…

Python 框架学习 Django篇 (六) 数据表关联、ORM关联

在后端服务器开发中&#xff0c;特别是前后端分离的架构中数据库是非常重要的&#xff0c;后端主要就是负责管理数据&#xff0c;而我们经常使用的mysql、oracle 都是关系型数据库&#xff0c;什么是关系型数据库&#xff1f;就是建立在关系模型基础上的数据库&#xff0c;而最…

p5.js画布操作实战:创建,绑定指定元素,动态调整大小,隐藏滚动条,删除画布

文章简介 之前在 《p5.js 光速入门》 里粗略讲过一下如何使用 p5.js 创建画布。 这次要介绍几个 p5.js 提供的画布相关的方法。 创建画布时的相关配置。让画布绑定指定元素。重置画布大小。删除画布。 学习本文前你需要具备一点 p5.js 的知识&#xff0c;想了解的请查看 《p…

Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (一)

最近看了一个同事的几个视频。他总结的很好。在使用 LangChain 时&#xff0c;根据 LangChain 的官方文档 https://integrations.langchain.com/vectorstores&#xff0c;目前有三种方法可以进行使用&#xff1a;ElasticVectorSearch&#xff0c;ElasticsearchStore 及 Elastic…

洗衣行业在线预约小程序+前后端完整搭建教程

大家好哇&#xff0c;好久不见&#xff01;今天源码师父来给大家推荐一款洗衣行业在线预约的小程序&#xff0c;带有前后端的完整搭建教程。 目前&#xff0c;人们对生活品质的追求不断提高&#xff0c;但生活节奏却也不断加快。对品质的追求遇到了忙碌的生活节奏&#xff0c;…

计算机网络【CN】子网划分与子网掩码

一个子网定义(X.X.X.X/n) 子网掩码为 n 个 1&#xff0c;32-n 个 0包含的 IP 地址数&#xff1a;232−n 主机号全 0 表示本网段主机号全 1 表示网段的广播地址可分配的 IP 地址数 :232−&#x1d45b;−2 子网划分原则 满足子网定义子网&#x1d434;1…&#x1d434;&#x…

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.b…

宏电5G RedCap工业智能网关获首个中国移动5G物联网开放实验室5G及轻量化产品能力认证

10月21日&#xff0c;2023世界物联网博览会——中国移动物联网开发者大会暨物联网产业论坛在无锡圆满举行。宏电股份参与中国移动5G物联网开放实验室5G及轻量化产品能力认证成果授牌仪式&#xff0c;并获得认证证书。 此次认证主要对产品功能、产品性能、RedCap网络兼容性进行测…