LeetCode 面试经典 150_链表_合并两个有序链表(58_21_C++_简单)

LeetCode 面试经典 150_链表_合并两个有序链表(58_21_C++_简单)

题目描述:

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

输入输出样例:

示例 1:

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

示例 2:
输入 :l1 = [], l2 = []
输出:[]

示例 3:
输入 :l1 = [], l2 = [0]
输出:[0]

提示:

两个链表的节点数目范围是 [0, 50]

-100 <= Node.val <= 100

l1 和 l2 均按 非递减顺序 排列

题解:

解题思路:

思路一(迭代):

1、通过题目分析,将两个升序链表合并为一个新的 升序 链表并返回。我们可以将两个链表中较小的结点 插入到合并链表,直至两个链表结束。

2、具体思路如下:

① 创建一个临时结点当作连接两个链表的头结点。

② 每次将值较小的结点连接到合并链表,采用尾插法进行合并。

3、复杂度分析

① 时间复杂度:O(n+m),其中 n 和 m 分别为两个链表的长度。因为每次循环迭代中,list1 和 list2 只有一个元素会被放进合并链表中, 因此 while 循环的次数不会超过两个链表的长度之和。因此总的时间复杂度为 O(n+m)。

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

代码实现

代码实现(思路一(迭代)):
cpp 复制代码
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        //创建一个临时结点当作连接两个链表的头结点 
		ListNode *prehead=new ListNode(-1);
		//采用尾插法进行合并 
		ListNode *tail=prehead;
		//每次将值较小的结点连接到合并链表 
		while(list1!=nullptr&&list2!=nullptr){
			if(list1->val<list2->val){
				tail->next=list1;
				list1=list1->next;
			}else{
				tail->next=list2;
				list2=list2->next;
			}
			//每次都连接一个结点后,tail向后移动一次记录末尾 
			tail=tail->next;
		}
		//注意这里连接一个结点,就是连接一串结点(未连接部分本来就是链表) 
		tail->next=(list1!=nullptr) ? list1 : list2;
		
		//注意合并的结点是从第二个结点开始 
		return prehead->next;
    }
};
以思路一为例完成代码调试
cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;

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){}
};

//创建单链表
ListNode *createList(vector<int> arr){
	ListNode *head=nullptr,*tail=nullptr;
	for(const auto val:arr){
		ListNode* newNode=new ListNode(val);
		if(head==nullptr){
			head=newNode;
			tail=newNode;
		}else{
			tail->next=newNode;
			tail=newNode;
		}
	}
	return head;
}

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        //创建一个临时结点当作连接两个链表的头结点 
		ListNode *prehead=new ListNode(-1);
		//采用尾插法进行合并 
		ListNode *tail=prehead;
		//每次将值较小的结点连接到合并链表 
		while(list1!=nullptr&&list2!=nullptr){
			if(list1->val<list2->val){
				tail->next=list1;
				list1=list1->next;
			}else{
				tail->next=list2;
				list2=list2->next;
			}
			//每次都连接一个结点后,tail向后移动一次记录末尾 
			tail=tail->next;
		}
		//注意这里连接一个结点,就是连接一串结点(未连接部分本来就是链表) 
		tail->next=(list1!=nullptr) ? list1 : list2;
		
		//注意合并的结点是从第二个结点开始 
		return prehead->next;
    }
};

int main(){
	vector<int> a={1,2,4};
	vector<int> b={1,3,4};
	ListNode *list1=createList(a);
	ListNode *list2=createList(b);
	Solution s;
	ListNode *mergeList=s.mergeTwoLists(list1,list2);
	while(mergeList!=nullptr){
		cout<<mergeList->val<<"->";
		mergeList=mergeList->next;
	}
	cout<<"null";
	return 0;
} 

LeetCode 面试经典 150_链表_合并两个有序链表(58_21)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
橘颂TA18 分钟前
【剑斩OFFER】算法的暴力美学——数青蛙
算法·leetcode·动态规划·结构与算法
CoderYanger1 小时前
动态规划算法-简单多状态dp问题:12.打家劫舍Ⅱ
开发语言·算法·leetcode·职场和发展·动态规划·1024程序员节
敲敲了个代码1 小时前
从零实现一个「就地编辑」组件:深入理解 OOP 封装与复用的艺术
前端·javascript·学习·面试·前端框架
金融小师妹1 小时前
机器学习驱动分析:ADP就业数据异常波动,AI模型预测12月降息概率达89%
大数据·人工智能·深度学习·编辑器·1024程序员节
王中阳Go2 小时前
Go后端 vs Go AI应用开发重点关注什么?怎么学?怎么面试?
人工智能·面试·golang
程序员小胖2 小时前
每天一道面试题之架构篇|异步确保型事务——消息队列驱动的分布式事务解决方案
分布式·面试
java修仙传2 小时前
力扣hot100:最长连续序列
算法·leetcode·职场和发展
是你的小橘呀2 小时前
像前任一样捉摸不定的异步逻辑,一文让你彻底看透——JS 事件循环
前端·javascript·面试
Pluchon2 小时前
硅基计划4.0 算法 记忆化搜索
java·数据结构·算法·leetcode·决策树·深度优先