合并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. Tensorflow之实现物体检测

    目录 项目背景 TensorFlow介绍 环境搭建 模型选用 Api使用说明 运行路由 小结 项目背景 产品看到竞品可以标记物体的功能,秉承一贯的他有我也要有,他没有我更要有的作风,丢过来一网站,说这 ...

  2. 使用PowerShell 自动安装IIS 及自动部署网站

    执行环境:Windows Server 2012 R2 安装iis核心代码,可自定义安装项 注意这里不能使用add-windowsfeature  "Web-Filtering", ...

  3. poj2152 Fire(树形DP)

    题目链接:https://vjudge.net/problem/POJ-2152 题意:给定一颗大小为n的树,在每个结点建消防站花费为w[i],如果某结点没有消防站,只要在它距离<=d[i]的结 ...

  4. #######【Python】【基础知识】【标准库】目录及学习规划 ######

    下述参考Python DOC https://docs.python.org/zh-cn/3/library/index.html 概述 可用性注释 内置函数 内置常量 由 site 模块添加的常量 ...

  5. 走近kafka-文件存储

    过期的数据才会被自动清除以释放磁盘空间.比如我们设置消息过期时间为2天,那么这2天内的所有消息都会被保存到集群中,数据只有超过了两天才会被清除. Kafka只维护在Partition中的offset值 ...

  6. SpringBoot起飞系列-国际化(六)

    一.前言 国际化这个功能可能我们不常用,但是在有需要的地方还是必须要上的,今天我们就来看一下怎么在我们的web开发中配置国际化,让我们的网站可以根据语言来展示不同的形式.本文接续上一篇SpringBo ...

  7. python基础知识0-2

    # !/usr/bin/env python # 提示输入用户名和密码 # 验证用户名和密码#     如果错误,则输出用户名或密码错误#     如果成功,则输出 欢迎,XXX! import ge ...

  8. Glide优化

    几乎所有的 OOM 错误都是因为宿主应用出了问题,而不是 Glide 本身. 应用里两种常见的 OOM 错误分别是: 过大的内存分配 (Excessively large allocations) 内 ...

  9. Asp.net core Identity + identity server + angular + odata + 权限管理

    今天踩了一个坑. 网站发布后看到了一个 error Refused to execute inline script because it violates the following Content ...

  10. 区间dp 整数划分问题

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...