leetcode 23. Merge k Sorted Lists(堆||分治法)
Merge k sorted linked lists and return it as one sorted list.
题意:把k个已经排好序的链表整合到一个链表中,并且这个链表是排了序的。
题解:这是一道经典好题,值得仔细一说。
有两种方法,假设每个链表的平均长度是n,那么这两种方法的时间复杂度都是O(nklogk)。
方法一:
基本思路是:把k个链表开头的值排个序,每次取最小的一个值放到答案链表中,这次取完之后更新这个值为它后面的一个值。接着这么取一直到全部取完。那么每次更新之后怎么对当前这k个值重新排序以便知道当前最小的是谁呢?用优先队列(或者堆)来维护这k个值就好啦!
由于每个值都要取一次,一共取nk次。每次更新优先队列要logk的复杂度。所以总时间复杂度为O(nklogk);空间复杂度为优先队列所占空间,为O(k)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
struct cmp
{
bool operator() (const ListNode* a,const ListNode* b)
{
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
priority_queue<ListNode*, vector<ListNode*>, cmp>pq;
for(auto i:lists)
{
if(i) //这句判断很有必要,不能把空的加入队列。比如这组数据:[[],[]]
{
pq.push(i);
}
}
if(pq.empty())
{
return nullptr;
}
ListNode* ans = pq.top();
pq.pop();
ListNode* tail = ans;
if(tail->next)
{
pq.push(tail->next);
}
while(!pq.empty())
{
tail->next = pq.top();
tail = tail->next;
pq.pop();
if(tail->next)
{
pq.push(tail->next);
}
}
return ans;
}
};
方法二:
和方法一的思路不同:考虑分治的思想来解这个题(类似归并排序的思路)。把这些链表分成两半,如果每一半都合并好了,那么我就最后把这两个合并了就行了。这就是分治法的核心思想。
但是这道题由于存的都是指针,就具有了更大的操作灵活性,可以不用递归来实现分治。就是先两两合并后在两两合并。。。一直下去直到最后成了一个。(相当于分治算法的那棵二叉树从底向上走了)。
第一次两两合并是进行了k/2次,每次处理2n个值。
第二次两两合并是进行了k/4次,每次处理4n个值。
。。。
最后一次两两合并是进行了k/(2^logk)次,每次处理2^logK*N个值。
所以时间复杂度:
O((2N) * (K / 2) + (4N) * (K / 4) + (8N) * (K / 8) + .............. + (2^logK*N) * (K / (2 ^logK)) )=O( logK*KN)
空间复杂度是O(1)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty()){
return nullptr;
}
while(lists.size() > ){
lists.push_back(mergeTwoLists(lists[], lists[]));
lists.erase(lists.begin());
lists.erase(lists.begin());
}
return lists.front();
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
if(l1 == nullptr){
return l2;
}
if(l2 == nullptr){
return l1;
}
if(l1->val <= l2->val){
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else{
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};
leetcode 23. Merge k Sorted Lists(堆||分治法)的更多相关文章
- 蜗牛慢慢爬 LeetCode 23. Merge k Sorted Lists [Difficulty: Hard]
题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...
- [LeetCode] 23. Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...
- [LeetCode] 23. Merge k Sorted Lists ☆☆☆☆☆
转载:https://leetcode.windliang.cc/leetCode-23-Merge-k-Sorted-Lists.html 描述 Merge k sorted linked list ...
- LeetCode 23 Merge k Sorted Lists(合并k个有序链表)
题目链接: https://leetcode.com/problems/merge-k-sorted-lists/?tab=Description Problem: 给出k个有序的list, 将其进行 ...
- [LeetCode] 23. Merge k Sorted Lists ☆☆
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解 ...
- [leetcode 23]Merge k Sorted Lists
1 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...
- [leetcode]23. Merge k Sorted Lists归并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. I ...
- [LeetCode]23. Merge k Sorted Lists合并K个排序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...
- Java [leetcode 23]Merge k Sorted Lists
题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complex ...
随机推荐
- 动态载入Layout 与 论Activity、 Window、View的关系
1)动态载入Layout的代码是 getWindow().setContentView(LayoutInflater.from(this).inflate(R.layout.main, null)); ...
- IT项目管理-----给年轻工程师的十大忠告
http://blog.csdn.net/hbqhdlc/article/details/6201179给年轻工程师的十大忠告 诸位,咱当电子工程师也是十余年了,不算有出息,环顾四周,也没有看见几个有 ...
- netty 对 http 的实现
netty的http协议栈无论是性能还是可靠性,都表现优异,非常适合在非web容器场景 下应用,相比于tomcat.jetty等web容器,它更轻量.小巧.灵活性和定制性也好: 总结:只要实现了htt ...
- 《C专家编程》数组和指针并不同--多维数组
<C专家编程>数组和指针并不同 标签(空格分隔): 程序设计论著笔记 1. 背景理解 1.1 区分定义与声明 p83 声明相当于普通声明:它所说明的并不是自身,而是描写叙述其它地方创建的对 ...
- Java异常 - Exception总结
这篇blog总结的比较详细了. 如下图所示,在Java中所有异常的基类均为Throwable类.有两个子类,分别为Exception和Error.其中Error主要由JVM处理,比如OutOfMemo ...
- PowerBuilder -- 未公开函数
原文:http://blog.csdn.net/happymagic/article/details/51077322 @.已知一个DW中的某列的列名(在字符串变量中),以获得这个列对象的DWO 方法 ...
- Oracle 10g ORA-12154: TNS: could not resolve the connect identifier specified 问题解决! 我同事遇到的问题。 username/
Oracle 10g ORA-12154: TNS: could not resolve the connect identifier specified 问题解决! 我同事遇到的问题. userna ...
- 离线安装Cloudera Manager5.3.4与CDH5.3.4(一)
这几天一直在安装CDH,头都搞大了,安装第三次,最终成功了. 第一次问题非常多.后面卸载了.由于没有卸载干净导致第二次安装失败. 后来索性重装系统了.直接使用了纯净系统进行安装.一个人跑到学院机房去装 ...
- POJ3182 The Grove[射线法+分层图最短路]
The Grove Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 904 Accepted: 444 Descripti ...
- 对EasyDarwin开源项目后续发展的思考:站在巨人的肩膀上再跳上另一个更高的肩膀
2017 EasyDarwin现状 自从2012年EasyDarwin项目创立开始,经过了快5年了,时光飞逝,如今EasyDarwin已经发展成为了不仅仅是一个单纯的开源流媒体服务器项目了,已经是各种 ...