Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
算法一:最简单的做法就是先1、2合并,12结果和3合并,123结果和4合并,…,123..k-1结果和k合并。两两合并的时候可以用递归的方法。
我们计算一下复杂度。
1、2合并,遍历2n个节点
12结果和3合并,遍历3n个节点
123结果和4合并,遍历4n个节点
…
123..k-1结果和k合并,遍历kn个节点
总共遍历的节点数目为n(2+3+…+k) = n*(k^2+k-2)/2, 因此时间复杂度是O(n*(k^2+k-2)/2) = O(nk^2),代码如下:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.size()==0) return NULL;
ListNode* list = lists[0];
if(lists.size()>1)
for(int i=1; i<lists.size(); i++)
{
list = merge2Lists(list, lists[i]);
}
return list;
}
ListNode* merge2Lists(ListNode* list1, ListNode* list2)
{
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
if(list1->val<=list2->val)
{
list1->next = merge2Lists(list1->next, list2);
return list1;
}
if(list1->val>list2->val)
{
list2->next = merge2Lists(list1, list2->next);
return list2;
}
}
上面的算法复杂度太高,OJ会给出超时的错误。
算法二:用最大堆作为辅助排序工具:
/**
* 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) {
vector<ListNode *> heap;//min heap
for(int i=0; i<lists.size(); i++)
{// make sure that all nodes pushed into the heap are non-empty nodes
if(lists[i]!=NULL)
heap.push_back(lists[i]);
}
if(heap.size()==0) return NULL;
build_heap(heap);
ListNode* head = NULL;
ListNode* curr = head;
while(heap.size()>0)
{
if(head==NULL)
{
head = heap[0];
curr = head;
}
else
{
curr->next = heap[0];
curr = curr->next;
}
if(heap[0]->next)
heap[0] = heap[0]->next;
else
{
if(heap.size()>1)
heap[0] = heap.back();
heap.resize(heap.size()-1);
}
if(heap.size()>0)
heapify(heap, 0);
}
return head;
}
void heapify(vector<ListNode*>& heap, int i)
{
int left = 2*i+1;
int right = 2*i+2;
int small = i;
if( left<heap.size() )
{
if(heap[left]->val<heap[small]->val )
small = left;
}
if( right<heap.size() )
{
if(heap[right]->val<heap[small]->val )
small = right;
}
if(small!=i)
{
swap(heap[i], heap[small]);
heapify(heap, small);
}
}
void build_heap(vector<ListNode*>& heap)
{
for(int i=( heap.size()-1 )/2; i>=0; i--)
{
heapify(heap, i);
}
}
};