题目来源leetcode 23
给定k个排好序的序列,要求归并他们为一个排好序的序列。
从第一个序列开始,一个一个地归并是一种简单的做法。然而复杂度是多少呢?假设序列平均长度为n,那么这种做法所需要的时间可以这样计算:2n+3n+4n+......+kn。最后,n可以看作是一个常熟,这样得到是O(k^2)的复杂度。我们寻求更好的办法。
采用分治策略,对于一组要合并的序列,先合并前一半序列,再合并后一半的序列,这种思路和归并排序其实相当类似。复杂度可以采用递推关系T(k)=2T(k/2)+O(k)计算。最后一项的O(k)所代表的其实是归并所需要的复杂度,因为在归并两个由k/2个序列归并出来的序列,假设原序列平均长度是常数的话,那么序列长度是O(k)级的。这样就得到最终的复杂度O(klogk)
ListNode* merge(ListNode* List1, ListNode* List2)
{
ListNode* pointer1 = List1;
ListNode* pointer2 = List2;
ListNode* ans=new ListNode(0);
ListNode* pointer = ans;
if (!pointer1&&!pointer2)
return NULL;
while (1)
{
if (!pointer1)
{
pointer->val = pointer2->val;
pointer2 = pointer2->next;
}
else
{
if (!pointer2)
{
pointer->val = pointer1->val;
pointer1 = pointer1->next;
}
else
{
if (pointer1->val > pointer2->val)
{
pointer->val = pointer2->val;
pointer2 = pointer2->next;
}
else
{
pointer->val = pointer1->val;
pointer1 = pointer1->next;
}
}
}
if (!pointer1&&!pointer2)
break;
pointer->next = new ListNode(0);
pointer = pointer->next;
}
return ans;
}
ListNode* mergeKLists(vector<ListNode*>& lists,int left,int right)
{
if(lists.size()==0)
return NULL;
if (left == right)
return lists[left];
ListNode* List1 = mergeKLists(lists, left, (left + right) / 2);
ListNode* List2 = mergeKLists(lists, (left + right) / 2+1, right);
return merge(List1, List2);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return mergeKLists(lists,0,lists.size()-1);
}