外排序,及k路归并算法是一个很重要的算法,大数据用也会用到。
http://shmilyaw-hotmail-com.iteye.com/blog/1776132
此题,准备用两种方法来解。第一种是用Priority Queue, 简单好想。注意用了c++ Lamda Function, 来定义pque的compare function。
ListNode *mergeKLists(vector<ListNode *> &lists) {
// write your code here
if(lists.empty()) return NULL;
auto comp = [](const ListNode *l1, const ListNode *l2){
return l1->val > l2->val;
};
priority_queue<ListNode*, vector<ListNode*>, decltype(comp)> pque(comp);
ListNode *dummy = new ListNode(0);
ListNode *pre = dummy;
for(ListNode* it : lists){
if(it != NULL) pque.push(it);
}
while(!pque.empty()){
ListNode *cur = pque.top(); pque.pop();
pre->next = cur;
pre = pre->next;
if(cur->next) pque.push(cur->next);
}
pre = dummy->next;
delete dummy;
return pre;
}
第二种是Divide and Conquer,这种难想一些, 但实现起来并不复杂。
我们把k个list从中间分一半,先合并上k/2 (0 - k/2), 再合并下k/2 (k/2+1 - k),最后再merge。对上一半,下一半也分别采用相同的方法,先切一半,再合起来。MergeSort的思想。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.empty()) return NULL;
int size = lists.size();
return sortList(lists, 0, size-1);
}
ListNode *sortList(vector<ListNode*>& lists, int start, int end){
if(start > end) return NULL;
else if(start == end){
return lists[start];
}
int mid = start + (end-start)/2;
return merge(sortList(lists, start, mid), sortList(lists, mid+1, end));
}
ListNode *merge(ListNode *headA, ListNode *headB){
if(!headA) return headB;
else if(!headB) return headA;
ListNode *dummy = new ListNode(0);
ListNode *pre = dummy;
while(headA && headB){
if(headA->val < headB->val){
pre->next = headA;
headA = headA->next;
}
else{
pre->next = headB;
headB = headB->next;
}
pre = pre->next;
}
pre->next = headA ? headA : headB;
pre = dummy->next;
delete dummy;
return pre;
}
};
网友评论