外排序二拐,及k路歸并算法是一個(gè)很重要的算法,大數(shù)據(jù)用也會(huì)用到。
http://shmilyaw-hotmail-com.iteye.com/blog/1776132
此題提完,準(zhǔn)備用兩種方法來解。第一種是用Priority Queue, 簡(jiǎn)單好想丘侠。注意用了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,這種難想一些, 但實(shí)現(xiàn)起來并不復(fù)雜蜗字。
我們把k個(gè)list從中間分一半打肝,先合并上k/2 (0 - k/2), 再合并下k/2 (k/2+1 - k),最后再merge挪捕。對(duì)上一半粗梭,下一半也分別采用相同的方法,先切一半担神,再合起來楼吃。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;
}
};