合并K个已排序的链表。返回一个排序链表

217 篇文章 0 订阅
174 篇文章 2 订阅

本题源自LeetCode

-------------------------------------------------------------

思路1 : 优先队列

1 遍历所有的链表,将首节点放入优先队列。

2 取出优先队列的头,即最小的节点。链接到新链表的尾部。

3 如果队列首节点的链表不空,就将下一个节点入队列。依次循环1-3步。

代码:

  struct compare{
        bool operator()(const ListNode* a,const ListNode* b){
            return a->val > b->val;
        }
    };
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        priority_queue<ListNode*,vector<ListNode*>,compare> que;  //优先队列
        for(auto node:lists){
            if(node)
            	que.push(node);
        }
        if(que.empty())
            return NULL;
        ListNode* root=new ListNode(0);
        root->next=NULL;
        ListNode* pre=root;
        while(que.size()){
            ListNode* p=que.top();    //取队列头部,最小的那个节点
            que.pop();
            pre->next=p;
            pre=p;
            if(pre->next){           //取节点那个链表不空,向后遍历
                que.push(pre->next);
            }
        }
        return root->next;
    }

思路 2 : 最小堆

1  和上面一样遍历 各链表首节点 然后建堆

2 取出堆顶点,然后调整堆

3 如果当前最小节点的链表不空,则下一个节点入堆,调整堆,循环

代码:

    struct compare{
        bool operator()(const ListNode* a,const ListNode* b){
            return a->val > b->val;
        }
    };
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        vector<ListNode*> vec;    //最小堆
        for(auto node:lists){
            if(node)
                vec.push_back(node);
        }
        ListNode* root=new ListNode(0);
        root->next=NULL;
        ListNode* pre=root;
        make_heap(vec.begin(),vec.end(),compare());   //建堆
        while(vec.size()){
            pre->next=vec[0];
            pop_heap(vec.begin(),vec.end(),compare());   //将第一个节点与最后一个作交换
            vec.pop_back();  //删除最后一个节点
            pre=pre->next;
            if(pre->next){
                vec.push_back(pre->next);
                push_heap(vec.begin(),vec.end(),compare());
            }
        }
        return root->next;
        
    }

思路3

归并排序。先两两合并然后在合并

代码:

 ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.size()==0)
            return NULL;
        while(lists.size()>1){
            lists.push_back(mergeList(lists[0],lists[1]));
            lists.erase(lists.begin());
            lists.erase(lists.begin());
        }
        return lists.front();
    }
    ListNode* mergeList(ListNode* l1,ListNode* l2){
        if(l1==NULL)
            return l2;
        if(l2==NULL)
            return l1;
        if(l1->val<l2->val){
            l1->next=mergeList(l1->next,l2);
            return l1;
        }else{
            l2->next=mergeList(l1,l2->next);
            return l2;
        }
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值