Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input: [ 1->4->5, 1->3->4, 2->6 ] Output: 1->1->2->3->4->4->5->6
hard难度的就是不一样。
思路转自这个博客
用最小堆来解决,
在c++里,我们可以使用STL重的priority_queue,而在java中可使用PrioirtyQueue, 注意的是STL重的priority_queue默认为最大堆,所以我们要改变比较算法,因为ListNode为自定义类,我们需要重载比较方法。
利用最小堆,首先先把list中所有的listnode放进最小堆中,然后每次取出头部并与返回的链表相连。
c++官方api:http://www.cplusplus.com/reference/queue/priority_queue/
声明:priority_queue<Type, Container, Functional>
其中type为数据类型,container为存储数据的容器,functional为比较数据的方法,一般默认为container为vector,而functional为<, 即为最大堆,优先输出大的元素。
对于内置数据类型,如int,想要改变输出的比较方式
可以通过 priority_queue<int, vector<int>, greater<int> > 来改变
对于自定义数据类型,可以重载操作符,即
struct cmp{ bool operator() (ListNode *a, ListNode* b){ return a->val > b->val; } };
operator()重载函数需要被定义(声明)在一个新的结构体内
我们再来看另一种解法,这种解法利用了 最小堆 这种数据结构,我们首先把k个链表的首元素都加入最小堆中,它们会自动排好序。然后我们每次取出最小的那个元素加入我们最终结果的链表中,然后把取出元素的下一个元素再加入堆中,下次仍从堆中取出最小的元素做相同的操作,以此类推,直到堆中没有元素了,此时k个链表也合并为了一个链表,返回首节点即可struct cmp{
bool operator()(ListNode *a,ListNode *b){//注意写法,这里有个括号
return a->val > b->val;//a比b大的话,就交换,把b放到前面,实现最小堆
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp> q;
for(int i=0;i<lists.size();i++){
if(lists[i]) q.push(lists[i]);
}
ListNode *head=NULL,*now=NULL,*tmp=NULL;
while(!q.empty()){
tmp=q.top();
q.pop();
if(head==NULL){
now=head=tmp;//给头指针赋值
//now不用跳,因为此时now->next还没有值
}else{
now->next=tmp;//把tmp赋值给now的下一个
now=now->next;//now跳到下一个
}
if(tmp->next) q.push(tmp->next);
}
return head;
}
};