Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
比较自然地想到以下三种方法,设k个链表 每个链表n个元素。
1.暴力法
每次遍历k个表头找出最小的元素,O(k),共O(nk)个元素 总复杂度O(nk^2)
2.分治法
两两合并
方便起见 设k=2^r,
第一层进行k/2次合并操作,操作规模为2n(两个规模为n的表),总操作数为kn,
第二次进行k/4次合并操作,操作规模为4n(两个规模为2n的表),总操作为kn,
……
最后一次进行1次合并操作,操作规模为kn(两个规模为kn/2的表),总操作为kn,
层数为r,则总复杂度为O(nk logk )
3. 逐一合并
第一次 两个规模为n的链表合并,操作规模为2n,
第二次 规模2n的链表与n的链表合并,操作规模为3n,
……
最后一次 规模(k-1)n的链表与n的链表合并,操作规模kn,
由等差数列求和公式 得复杂度O(nk^2)
因此 分治法复杂度明确更低 采用分治法更好、
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
return Helper(lists,0,n-1);
}
ListNode* Helper(vector<ListNode*>& lists,int begin,int end){
if(begin>end){return NULL;}
if(begin==end){return lists[begin];}
if(begin+1==end){
ListNode *newhead = NULL;
ListNode *p = newhead;
ListNode *p1 = lists[begin];
ListNode *p2 = lists[end];
if(p1==NULL||p2==NULL){
if(p1==NULL) return p2;
else return p1;
}
if(p1->val<=p2->val){
p = p1;
p1=p1->next;
}
else{
p= p2;
p2=p2->next;
}
newhead = p;
while(p1!=NULL&&p2!=NULL){
if(p1->val<=p2->val){
p->next = p1;
p1=p1->next;
}
else{
p->next= p2;
p2=p2->next;
}
p=p->next;
}
if(p1==NULL){p->next=p2;}
else{p->next=p1;}
return newhead;
}
vector<ListNode*> newlists;
newlists.push_back(Helper(lists,begin,(begin+end)/2));
newlists.push_back(Helper(lists,((begin+end)/2)+1,end));
return Helper(newlists,0,1);
}
};