NC51_合并k个已排序的链表
知识点:归并、最小堆
题目链接
题目描述
合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。
输入: [{1,2,3},{4,5,6,7}]
输出: {1,2,3,4,5,6,7}
解题思路
- 归并排序 注意返回值
- 最小堆,注意在合并的时候 需要把链表的下一个结点也放进去
代码
#include "cheader.h"
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
//1. 归并排序 时间 O(k*n*log_k) 空间 O(log_k)
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
return merge_sort(lists, 0, lists.size()-1);
}
ListNode* merge_sort(vector<ListNode*>& lists,int l,int r){
if(l > r)
return nullptr;
else if(l == r)
return lists[l];
int mid = l + (r-l)/2;
ListNode* n1 = merge_sort(lists, l, mid);
ListNode* n2 = merge_sort(lists, mid+1, r);
return merge(n1,n2);
}
ListNode* merge(ListNode* x,ListNode* y){
ListNode *head = new ListNode(-1);
ListNode *temp = head;
while(x != nullptr && y != nullptr){
if(x->val <= y->val){
temp->next = x;
x = x->next;
}else{
temp->next = y;
y = y->next;
}
temp = temp->next;
}
if(x!=nullptr) temp->next = x;
else if(y != nullptr) temp->next = y;
return head->next;
}
};
//2. 小根堆 时间O(k*n*log_n) 空间O(k)
class Solution {
public:
struct compare{
bool operator()(const ListNode* x,const ListNode* y){
return x->val > y->val;
}
};
ListNode *mergeKLists(vector<ListNode *> &lists){
priority_queue<ListNode*,vector<ListNode*>,compare> q;
for(ListNode* x : lists)
if(x != nullptr)
q.push(x);
if(q.empty())
return nullptr;
ListNode* head = new ListNode(-1);
ListNode* tmp = head;
while(!q.empty()){
tmp->next = q.top();
q.pop();
tmp = tmp->next;
if(tmp->next) //注意要放回去 把链表的后一个元素放入
q.push(tmp->next);
}
return head->next;
}
};
今天也是爱zz的一天!