LeetCode:合并k个有序的链表

You are given an array of k linked-lists,each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.

Example 1:
Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
  1->4->5,
  1->3->4,
  2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

Example 2:
Input: lists = []
Output: []

Example 3:
Input: lists = [[]]
Output: []
 
题目大意:
给定k个增序的链表,试将它们合并成一条增序链表.

解题思路:
方法1:
枚举数组中所有链表的元素,存储在一个数组中,然后进行排序,即可.时间复杂度为O(n),空间复杂度也为O(n).

方法2:
分治思想,先每次拆分成k/2.最终再进行合并.

方法3:
优先队列.把所有的链表存储在一个优先队列中,每次提取所有链表头部节点值最小的那个节点,直到所有链表都被提取完.
需要设置一个比较类Comp,实现最小堆.因此operate()中返回时用大于号而不是等增关系的小于号进行比较.
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct ListNode{
    int val;
    ListNode* next;
    ListNode():val(0),next(nullptr){}
    ListNode(int x):val(x),next(nullptr){}
    ListNode(int x,ListNode* next):val(x),next(next){}
};

class Solution{
public:
     Solution(){
         root=new ListNode(0);//利用指针,在堆上开辟空间,不能用栈上的局部变量返回地址.
         tmp=nullptr;
     }
     ListNode* mergeKLists(vector<ListNode*>& lists){
         if(lists.empty()) return nullptr;
         vector<int> res;
         for(auto& list:lists){
             while(list){
                 res.push_back(list->val);
                 list=list->next;
             }
         }
         sort(res.begin(),res.end()); 

         ListNode* head=root; 
         for(int i=0;i<res.size();i++){ 
             tmp=new ListNode(res[i]);  
             head->next=tmp;
             head=tmp;
         }  
         return root->next;//调试了很久,返回的根节点不存储值才行
     }

private:
     ListNode* root; 
     ListNode* tmp;
};

//方法二:归并排序
class SolutionOne{
public:
    ListNode* mergeKLists(vector<ListNode*>& lists){
        return merge(lists,0,lists.size()-1);
    }
    ListNode* merge(vector<ListNode*>& lists,int l,int r){
        if(l==r) return lists[l];
        if(l>r) return nullptr;
        int mid=(l+r)>>1;
        return MergeTwoLists(merge(lists,l,mid),merge(lists,mid+1,r));
    }

    ListNode* MergeTwoLists(ListNode* l,ListNode* r){
        if(l==nullptr||r==nullptr)
           return l?l:r;
        ListNode head,*tail=&head;
        ListNode *pre1=l,*pre2=r;
        while(pre1&&pre2){
            if(pre1->val<=pre2->val){
                tail->next=pre1;
                pre1=pre1->next;
            }else{
                tail->next=pre2;
                pre2=pre2->next;
            }
            tail=tail->next;
        }
        tail->next=(pre1?pre1:pre2);
        return head.next;
    }
};

//方法三:优先队列
class SolutionTwo{
public:
    ListNode* MergeKLists(vector<ListNode*>& lists){
        if(lists.empty()) return nullptr;
        //priority_queue默认三个参数
        //Type就是数据类型,Container就是容器类型(Container必须是用数组实现的容器,
        //比如vector,deque等等,但不能用 list.STL里面默认用的是vector),Functional 就是比较的方式。
        priority_queue<ListNode*,vector<ListNode*>,Comp> q;
        for(ListNode* list:lists){
            if(list){
                q.push(list);
            }
        }
        ListNode root;
        ListNode* dummy=&root,*cur=dummy;
        while(!q.empty()){
            cur->next=q.top();
            q.pop();
            cur=cur->next;
            if(cur->next){
                q.push(cur->next);
            }
        }
        return root.next;
    }

    struct Comp{
        bool operator()(ListNode* l1,ListNode* l2){
            return l1->val>l2->val; //最小堆
        }
    };
};
int main(int argc,char* argv[]){

    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值