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)原题链接

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

相关推荐
Lee川8 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
Lee川11 小时前
从异步迷雾到优雅流程:JavaScript异步编程与内存管理的现代化之旅
javascript·面试
晴殇i13 小时前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
绝无仅有14 小时前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有14 小时前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
AAA梅狸猫15 小时前
Looper.loop() 循环机制
面试
AAA梅狸猫15 小时前
Handler基本概念
面试
Wect15 小时前
浏览器缓存机制
前端·面试·浏览器
掘金安东尼16 小时前
Fun with TypeScript Generics:玩转 TS 泛型
前端·javascript·面试
掘金安东尼16 小时前
Next.js 企业级落地
前端·javascript·面试