合并K个sorted list
合并k个已经排好序的数列是面试中也比较容易被问到的一个算法,有很多种解决,其中第一时间比较容易想到的解法如下:
对于这三组从小到大的数列:








如此循环,最终就将三个已经排序的数列的数字按从小到大的顺序排序到最终结果集了,那先来看一下这种算法的时间复杂度:
如果总共有k个排序好的数列,而几个数列中的总数字为n个,每拿一个数都要进行k次的循环比较,很明显其时间复杂度T(n) = O(n*k)。
那如果面试官问你如何对它进行优化呢?也就是用一个效率更高的算法来代替它,这时就需要用到之前学过的最小堆去优化啦,因为每次最小堆的根结点就是该数列的最小值,所以说用最小堆去实现的话也就是将每个数列中待比较的数字都放到最小堆中,其中涉及到交换元素,最终拿根结点就可以拿到最小的值了,这样对于k个数列来说其时间复杂度也就是logk,比之前的要比较k次才能得到最小值效率要高,也就是利用最小堆实现合并排序数列的时间复杂度T(n) = O(n * logk),当k值越大时,其logk比k远远要小很多,当然如果K值比较小其优化力度体现不是特别明显,所以在回答面试官时需要强调:在K值比较多的情况下用最小堆去优化是一个比较好的方案。
所以接下来就是来看一下如何来实现这种优化的算法,这里采用JAVA来实现,因为实现起来也比较好理由,下面先来搭建框架:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue; public class MergeKList { //用链表来表达数列
static class ListNode {
int value;
ListNode next; ListNode(int value) {
this.value = value;
}
} //开始合并有序序列
private void mergeKLists(ArrayList<ListNode> lists) {
//TODO
} public static void main(String[] args) {
//构造三个有序数列
ListNode h1 = new ListNode(2);
h1.next = new ListNode(5);
h1.next.next = new ListNode(7); ListNode h2 = new ListNode(3);
h2.next = new ListNode(9);
h2.next.next = new ListNode(10); ListNode h3 = new ListNode(1);
h3.next = new ListNode(4); ArrayList<ListNode> lists = new ArrayList<ListNode>();
lists.add(h1);
lists.add(h2);
lists.add(h3); new MergeKList().mergeKLists(lists);
} }
接着就是实现核心的合并方法:mergeKLists(),这里需要涉及到优先队列:PriorityQueue:

其中它就是用堆来实现的,所以功能跟堆类似,将一堆数字添加到优先队列中,最终拿的话按一定的条件拿。对于Queue我们已经非常熟了,先进先出,也就是先进去的先出来,但是!!这个优先队列是按条件来出的,可以最小的元素先出来,有了这么一个现成的类那实现就显得异常简单啦,所以这也是为啥要采用java来实现的原因,具体如下:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue; public class MergeKList { //用链表来表达数列
static class ListNode {
int value;
ListNode next; ListNode(int value) {
this.value = value;
}
} //开始合并有序序列
private void mergeKLists(ArrayList<ListNode> lists) {
PriorityQueue<ListNode> q = new PriorityQueue<ListNode>(lists.size(),
new Comparator<ListNode>(){
public int compare(ListNode a, ListNode b) {
return a.value - b.value;
}
}); //将每个序列的数添加到优先队列中
for(ListNode list : lists) {
q.add(list);
} while(q.size() > 0) {
ListNode temp = q.poll();//直接拿出最小的元素,由优先队列类来保证
System.out.println(temp.value);
if(temp.next != null)
q.add(temp.next);//如果当前序列有下一个元素则直接将它再加入到优先队列中
}
} public static void main(String[] args) {
//构造三个有序数列
ListNode h1 = new ListNode(2);
h1.next = new ListNode(5);
h1.next.next = new ListNode(7); ListNode h2 = new ListNode(3);
h2.next = new ListNode(9);
h2.next.next = new ListNode(10); ListNode h3 = new ListNode(1);
h3.next = new ListNode(4); ArrayList<ListNode> lists = new ArrayList<ListNode>();
lists.add(h1);
lists.add(h2);
lists.add(h3); new MergeKList().mergeKLists(lists);
} }
编译运行:

由于比较简单,所以这里就不debug啦~~
合并K个sorted list的更多相关文章
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...
- [Swift]LeetCode23. 合并K个排序链表 | Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...
- 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合并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 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...
- LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)
23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...
- 023 Merge k Sorted Lists 合并K个有序链表
合并K个有序链表,并且作为一个有序链表的形式返回.分析并描述它的复杂度. 详见:https://leetcode.com/problems/merge-k-sorted-lists/descripti ...
- Leetcode23--->Merge K sorted Lists(合并k个排序的单链表)
题目: 合并k个排序将k个已排序的链表合并为一个排好序的链表,并分析其时间复杂度 . 解题思路: 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后 ...
- LeetCode 23. 合并K个排序链表(Merge k Sorted Lists)
题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: ...
随机推荐
- HP LaserJet M602 更換碳粉盒CE390XC
HP LaserJet M602 原裝碳粉盒為 CE390A 且容量小不夠用,故更換大號的 CE390XC ,需要將 CE390XC 外面的所有橙色部件去掉(取走上面一條帶2個凸起的遮罩,左側有一個耳 ...
- openstack——Rabbitmq集群部署
一.前期准备 1.条件:准备3台Linux系统虚拟机,保持系统版本一致,确保配置好yum源,及网络源 2.3台虚拟机做静态解析 [root@yun1 ~]# cat /etc/hosts 12 ...
- boostrap table接收到后台返回的数据格式不一致的解决方法
后台使用的分页插件是mybatis的PageHelper,返回数据格式如下: 而bootstrap table插件需要服务端返回的数据格式中含有"total"和"rows ...
- Android MVC MVP MVVM (二)
MVP模型 View主要是Activity,Fragment MVP和MVC的差别 1.Model和View不再直接通信,通过中间层Presenter来实现. 2.Activity的功能被简化,不再充 ...
- Python动态地声明变量赋值
通过exec().globals()和locals() # 通过exec() for i in range(1, 4): # 第一次循环 i=1 时,会执行字符串中的python语句 ex1 = &q ...
- idea连接docker实现一键部署
一.修改配置文件,打开2375端口 [root@microservice ~]# vim /usr/lib/systemd/system/docker.service 在ExecStart=/usr/ ...
- 基于.NET架构的树形动态报表设计与应用
在一些统计报表中,利用树形结构报表来实现维度钻取功能是十分常见的.通过逐级钻取,可以快速查看更细粒度的指标数据,如项目施工进度报告等. 使用葡萄城报表控件——ActiveReports ,即可轻松设计 ...
- Oracle通过正则表达式分割字符串 REGEXP_SUBSTR
REGEXP_SUBSTR函数格式如下: function REGEXP_SUBSTR(string, pattern, position, occurrence, modifier) string ...
- ARST第三周打卡
Algorithm : 做一个 leetcode 的算法题 //二位数组查找 题目描述 //在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺 ...
- phpexcel 生成大于26列数据
function excelExport2($fileName = '', $headArr = [], $data = [], $widths=[]) { ob_clean(); // $fileN ...