要求:rt
思路:
法一:归并,空间O(logk)(递归栈),时间O(n*klogk)(因为分治是O(klogk),合并要O(n))
/**
* 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* merge(ListNode* p1, ListNode* p2){
if(!p1) return p2;
if(!p2) return p1;
if(p1->val <= p2->val){
p1->next = merge(p1->next, p2);
return p1;
}else{
p2->next = merge(p1, p2->next);
return p2;
}
}
ListNode* merge(vector<ListNode*>& lists, int start, int end){
if(start == end) return lists[start];
int mid = (start + end) / 2;
ListNode* l1 = merge(lists, start, mid);
ListNode* l2 = merge(lists, mid+1, end);
return merge(l1, l2);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size() == 0) return nullptr;
return merge(lists, 0, lists.size()-1);
}
};
法二:优先队列,插删O(logk)),时间O(kn*logk)(kn个元素),空间O(k)
/**
* 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:
struct cmp{
bool operator()(ListNode *a,ListNode *b){
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp> pri_queue;
// 建立大小为k的小根堆
for(auto elem : lists){
if(elem) pri_queue.push(elem);
}
// 可以使用哑节点/哨兵节点
ListNode dummy(-1);
ListNode* p = &dummy;
// 开始出队
while(!pri_queue.empty()){
ListNode* top = pri_queue.top(); pri_queue.pop();
p->next = top; p = top;
if(top->next) pri_queue.push(top->next);
}
return dummy.next;
}
};