leetcode腾讯精选练习50(13)——合并K个排序链表

40 篇文章 0 订阅
13 篇文章 0 订阅

leetcode腾讯精选练习50(13)——合并K个排序链表

题目描述

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法思路

1.暴力法
有两种暴力法,一种是将所有元素放入一个链表中,重新排序;另一种是将链表逐个合并排序,这个时间复杂度会很大,前者还不错,时间复杂度时间复杂度:O(NlogN) ,其中N 是节点的总数目。

  • 遍历所有的值需花费O(N) 的时间。
  • 一个稳定的排序算法花费O(NlogN) 的时间。
  • 遍历同时创建新的有序链表花费O(N) 的时间。
  1. 优先队列
    一般队列都是先进先出,最小优先队列,无论入队顺序,当前最小的元素优先出队。这里用到了STL中的数据结构,我对STL不熟悉,是该多看看了。

3.分治
循环链表两两合并,直到得到最终链表。

代码

//优先队列
  struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
  };

class Solution {
public:
    struct cmp{bool operator()(ListNode* l1, ListNode* l2){return l1->val > l2->val;}};
    ListNode* mergeKLists(vector<ListNode*>& lists){
        ListNode* phead = new ListNode(0); ListNode* p = phead;
        if(lists.size() == 0) return nullptr;
        priority_queue<ListNode*, vector<ListNode*>, cmp> MinHeap;	//STL标准库中的优先队列,cmp是比较函数,决定队列是最小优先还是最大优先
        for(int i = 0;i < lists.size();i++) if(lists[i] != nullptr)MinHeap.push(lists[i]);
        while(!MinHeap.empty()){
            p->next = MinHeap.top();p = p->next;
            if(MinHeap.top()->next != nullptr) MinHeap.push(MinHeap.top()->next);MinHeap.pop();
        }
        return phead->next;
    }   
};
//分治
public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
 }

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(list.lengh==0)   return null;
        return mergeKLists(lists,0,lists.length-1);
    }
    public ListNode mergeKLists(ListNode[] lists,int l,int r){
        if(l==r)    return lists[l];

        int mid = (l+r)/2;
        ListNode l1 = mergeKLists(lists, l, mid);
        ListNode l2 = mergeKLists(lists, mid + 1, r);
        return mergeTwoLists(l1, l2);
    }

    private ListNode mergeTwoLists(ListNode l1,ListNode l2){
        if(l1==null)    return l2;
        else if(l2==null)    return l1;
        else if(l1.val<l2.val){
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }else{
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值