LeetCode 23-Merge k Sorted Lists(链表合并)

LeetCode 23 Merge k Sorted Lists

题干:

合并k个有序链表为一个升序链表。

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
-----------------
Input: lists = []
Output: []
-----------------
Input: lists = [[]]
Output: []

解:

合并k个有序链表的逻辑类似合并两个有序链表。问题是,如何快速得到k个节点中的最小节点,接到结果链表上?

用到了优先级队列(二叉堆),把链表节点放入一个最小堆,就可以每次获得k个节点中的最小节点。

复杂度:

  • 时间复杂度:O(nlogk)

  • 分析

  • 维护一个大小为k的最小值堆,每次维护复杂度O(logk)

  • 一共有n个数据,每个数据都会加入最小值堆,所以总体时间复杂度O(nlogk)

  • 比串成一个链表进行排序的O(nlogn)要小

  • 去掉空节点,k一定<=len

  • 所以比起完全无序的n个数据排序O(nlogn),该算法把复杂度降至O(nlogk)

  • 原因就在于数据部分有序

  • 启示:若给定数据部分有序,理应能时间复杂度优于O(nlogn)的算法

  • 空间复杂度:可直接改动原链表O(k),不允许破坏原链表O(n+k) ->需要确认!

  • 大小为k的最小值堆

  • 若不允许破坏原链表,需要额外O(n)

ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode dummy(-1, nullptr);
        ListNode* prev = &dummy;
        priority_queue<pair<int,ListNode*>, vector<pair<int, ListNode*>>, greater<pair<int, ListNode*>> > q;

        for(auto it: lists){
            if(it) q.push({it->val,it});
        }

        while(!q.empty()){
            prev->next = q.top().second;
            q.pop();
            prev = prev->next;
            if(prev->next) q.push({prev->next->val, prev->next});
        }
        prev->next = nullptr;
        return dummy.next;
    }

Tips

链表节点放入优先队列排序,类型可以是pair<int, ListNode*>,first放val值,second放节点。

priority_queue<pair<int,ListNode*>, vector<pair<int, ListNode*>>, greater<pair<int, ListNode*>> > q;  //最小堆

遍历vector的简便写法:for(auto it: lists)

for(int i = 0; i < lists.size(); i++){
    auto it = lists[i];
    if(it) q.push({it->val, it});
}
//等价于
for(auto it: lists){
    if(it) q.push({it->val,it});
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值