Merge k Sorted Lists

来源:互联网 发布:网站源码cmzy168 编辑:程序博客网 时间:2024/05/16 09:14
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
链表为降序,合并后也为降序。链表内不能变。
算法:

这里使用STL的priorit_queue,它是优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序,

每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储。例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优

先级高。所以我们无论按照什么顺序push一堆数,最终在队列里总是top出最大的元素,所以这里我们需要改成小顶堆。


该算法维护一个大小为k的堆,每次都会取堆顶的最小元素放到结果中,然后读取该元素的下一个元素(若为空,跳过)放入堆中,重新维护好。因为

每个链表是有序的,那么下次取得肯定是原链表的下一个元素(更小),每次又是取当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。这个算法每个

元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为

O(k)。


code
class Solution {
public:
struct cmp
{
bool operator() (ListNode *p1,ListNode* p2)
{
return p1->val > p2->val; // 第一个元素大于第二个元素,返回真时; 对应的是小根堆,升序!
} // 当想要大根堆,降序时,让它返回false就好,即用'<' (默认值)
};
ListNode* mergeKLists(vector<ListNode*>& lists) {

priority_queue<ListNode*,vector<ListNode*>,cmp> pq;

for (int i = 0; i < lists.size(); ++i) {
if(lists[i]!=NULL){
pq.push(lists[i]);
}
}
ListNode* tmp;
ListNode* head = NULL;
ListNode* pre = NULL;
while(!pq.empty()){
tmp = pq.top();
pq.pop();
if(pre==NULL)
head = tmp;
else
pre->next = tmp;
pre = tmp;
tmp = tmp->next;
if(tmp!=NULL)
pq.push(tmp);

}
return head;
}
};
0 0
原创粉丝点击