https://leetcode.com/problems/merge-k-sorted-lists/
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
CSDN坑爹博客,之前明明写过这篇,居然找不到了!
之前用JAVA写的代码,现在是用C++写的,JAVA的就不重写了。。。。代码跟这里差不多:
http://blog.csdn.net/linhuanmars/article/details/19899259
首先第一种方法是divide and conquer,就是先merge两个list,再依次往上。
假设每个链表最长长度为n,链表数为k,因此T(k) = 2*T(k/2) + O(nk), 因此时间复杂度是O(nk*logk),空间复杂度是递归栈的深度,O(logk)
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
return helper(lists, 0, lists.size()-1);
}
ListNode *helper(vector<ListNode *> &lists, int left, int right){
if(left>right) return NULL;
if(left==right) return lists[left];
int mid = (left+right)/2;
return merge(helper(lists, left, mid), helper(lists, mid+1, right));
}
ListNode *merge(ListNode* left, ListNode* right){
ListNode* dummy = new ListNode(0);
ListNode* trv = dummy;
while(left!=NULL && right!=NULL){
if(left->val < right->val){
trv->next = left;
left = left->next;
}
else{
trv->next = right;
right = right->next;
}
trv = trv->next;
}
if(left!=NULL) trv->next = left;
else trv->next = right;
ListNode * head = dummy->next;
delete dummy;
return head;
}
};
另一种方式是使用priority queue,即min_heap来排序,先放k个node到min_heap里面去,再从heap中取出来最小的,再把最小的的下一个放到heap中去。
时间复杂度是O(nk*logk),因为入栈深度是logk,总共nk个节点。空间复杂度O(k),注意,写priority queue的时候一定要记得覆盖比较函数,另外需要注意的是,C++的每个类定义后面都有一个分号,一定不能忘了,而且C++空指针是NULL,JAVA是null,不要弄混了:
class Comparison{
public:
bool operator()(ListNode* n1, ListNode * n2){
return n1->val > n2->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<ListNode *, vector<ListNode *>, Comparison> pq;
for(int i=0; i<lists.size(); i++){
if(lists[i] != NULL) pq.push(lists[i]);
}
ListNode *dummy = new ListNode(0);
ListNode *trv = dummy;
while(pq.size()>0){
trv->next = pq.top();
pq.pop();
trv = trv->next;
if(trv->next != NULL) pq.push(trv->next);
}
trv = dummy->next;
delete dummy;
return trv;
}
};