leetcode-23. Merge k Sorted Lists(优先队列priority_queue)

这篇博客讨论了如何合并k个已排序的链表,并将其作为一个整体排序链表返回。采用最小堆的方法,利用C++的STL库中的priority_queue或者Java的PriorityQueue。在C++中,由于priority_queue默认为最大堆,因此需要自定义比较函数。文章提供了官方API链接以及关于如何改变内置数据类型和自定义数据类型比较方式的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }   
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值