1、合并2个有序链表
题目链接
** 3、思路**
思路一:两个指针,开始遍历
思路二:递归
4、notes
搞一个dum前置节点做标记,
5、复杂度
时间:O(n+m)
空间:O(1)不算结果占用的空间,节点引用 dumdum , curcur 使用常数大小的额外空间
6、code
# 解法1、双指针
/**
* 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) {
auto h1 = list1;
auto h2 = list2;
ListNode * dummy_head = new ListNode(0); // 构造前一个节点
auto head = dummy_head; // 暂存起来
while(h1 && h2){ // 比较原始的两个链表,只要有一个遍历完 就跳出来
if(h1->val < h2->val){
head->next = h1;
h1 = h1->next;
}else {
head->next = h2;
h2 = h2->next;
}
head = head->next;
}
// 如果剩下的是h1
while(h1){
head->next = h1;
h1 = h1->next;
head = head->next;
}
// 如果剩下的是h2
while(h2){
head->next = h2;
h2 = h2->next;
head = head->next;
}
return dummy_head->next;
}
};
# 方法二:递归
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
if(!l2) return l1;
if(l1->val < l2->val)
{
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
}
2.1、合并K个有序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
来源:力扣(LeetCode)
链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
** 2、关键字**
有序,多组,合并,
** 3、思路**
多路归并,
使用双指针,这应该使用K个指针,比较出来最小的值,构造,比较也不算方便,所以使用优先队列,小根堆,维护那个最小的元素。Nlog(K)
** 4、notes**
1、优先队列+结构体 的基础知识
2、关于优先队列+lamba表达式的介绍2
默认大顶堆。
它的函数有:top(),pop(),size(),empty(),
2、构造小顶堆时候,第3个参数是一个仿函数。
** 5、复杂度**
时间:O(nlogK),n是节点总个数,K是优先队列的大小
空间:O(K),辅助空间,优先队列的大小。
6、code
/**
* 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) {}
* };
*/
// 优先队列:小根堆的回调函数
struct cmp{
bool operator()(ListNode * a, ListNode * b){
return a->val > b->val;
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*,vector<ListNode*>,cmp> que; // 定义优先队列,
//初始化大小为k的优先队列
for(auto & elem : lists){
if(elem){
que.push(elem);
}
}
auto dmp = new ListNode(-1); // 搞一个哑节点
auto cur = dmp;
while(!que.empty()){
auto top = que.top(); // 暂存,优先队列没有front函数,只有这个top函数
que.pop(); // 弹出
cur->next = top; // 加入结果集
cur = cur->next; // 结果集最后一个元素往后移,更新最后一个元素
if(top->next){ // 如果这个备选链表后边还有,就再加入到优先队列中,
que.push(top->next);
}
}
return dmp->next;
}
};