合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
- 通过堆来实现,每次将链表的首元素的最大值取出,可以利用优先级队列priority_queue来实现。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
struct cmp
{
bool operator() (const ListNode* a,const ListNode* b)
{
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
priority_queue<ListNode*, vector<ListNode*>, cmp>pq;
ListNode* ret=new ListNode(-1);
ListNode* p=ret;
for(int i=0;i<lists.size();i++)
{
if(lists[i])
pq.push(lists[i]);
}
while(pq.size()>0){
p->next=pq.top();
pq.pop();
p=p->next;
if(p->next!=NULL)
{
pq.push(p->next);
}
}
return ret->next;
}
};
复杂度分析:
-
Time complexity :O(Nlogk) wherek is the number of linked lists.
- The comparison cost will be reduced to (logk) for every pop and insertion to priority queue. But finding the node with the smallest value just costsO(1) time.
- There are N nodes in the final linked list.
-
Space complexity :
- O(n) Creating a new linked list costs O(n) space.
- O(k) The code above present applies in-place method which cost O(1) space. And the priority queue (often implemented with heaps) costs O(k)space (it's far less than N in most situations).