合并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的更多相关文章

  1. [LeetCode] Merge k Sorted Lists 合并k个有序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...

  2. [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 ...

  3. LeetCode 23 Merge k Sorted Lists(合并k个有序链表)

    题目链接: https://leetcode.com/problems/merge-k-sorted-lists/?tab=Description Problem: 给出k个有序的list, 将其进行 ...

  4. [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 ...

  5. [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 ...

  6. LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

    23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...

  7. 023 Merge k Sorted Lists 合并K个有序链表

    合并K个有序链表,并且作为一个有序链表的形式返回.分析并描述它的复杂度. 详见:https://leetcode.com/problems/merge-k-sorted-lists/descripti ...

  8. Leetcode23--->Merge K sorted Lists(合并k个排序的单链表)

    题目: 合并k个排序将k个已排序的链表合并为一个排好序的链表,并分析其时间复杂度 . 解题思路: 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后 ...

  9. LeetCode 23. 合并K个排序链表(Merge k Sorted Lists)

    题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: ...

随机推荐

  1. ASP.NET Core 入门笔记7,ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  2. 安装networking-sfc

    申明: 主参考:https://docs.openstack.org/networking-sfc/queens/ 辅参考: https://blog.csdn.net/linshenyuan1213 ...

  3. Windows Server 2019安装OpenSSH Server简明教程

    Windows Server 2019安装OpenSSH Server简明教程   Windows Server 2019内置OpenSSH Server组件了.只不过OpenSSH Server默认 ...

  4. Eslint常用命令

    Eslint常用命令 自动修复(针对整个项目) npm run lint -- --fix 运行如上命令,eslint 会自动修复一些简单的错误. 全局安装 npm install -g eslint ...

  5. 【VS开发】【计算机视觉】OpenCV读写xml文件《C版本》

    一些简单的XML读写操作,记之于笔记以备忘 主要功能: 1. 创建XML 2. 向XML中存储或者是读取Int float型基本数据 3. 通过创建XML元素,存取复杂的结构如:结构体.矩阵 代码如下 ...

  6. 使用nginx部署项目的相关资料

    1.简单的利用nginx部署前端项目 2.ubuntu 下 Nginx 的安装和配置 3.nginx配置文件nginx.conf超详细讲解 4.Nginx 安装与部署配置以及Nginx和uWSGI开机 ...

  7. Comparator接口实现排序

    对任意类型集合对象进行整体排序,排序时将此接口的实现传递给Collections.sort方法或者Arrays.sort方法排序.实现int compare(T o1, T o2);方法,返回正数,零 ...

  8. mac 查看占用的端口并关闭进程

    -i 查看某个端口是否被占用,如 lsof -i:8081 显示占用情况 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 12188 a ...

  9. 第三次Java实验报告

    Java实验报告 班级 计科二班 学号20188437 姓名 何磊 完成时间 2019/9/22 评分等级 实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档 ...

  10. SaltStack安装部署

    SaltStack安装部署 安装: 一. master: 1. 配置yum源安装 # rpm --import https://repo.saltstack.com/yum/redhat/6/x86_ ...