LeetCode: Merge k Sorted Lists 解题报告
Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Show Tags
参考资料: http://blog.csdn.net/linhuanmars/article/details/19899259。
SOLUTION 1:
使用分治法。左右分别递归调用Merge K sorted List,然后再使用merge linked list 合并在一起。
解答摘录如下:这 道题目在分布式系统中非常常见,来自不同client的sorted list要在central server上面merge起来。这个题目一般有两种做法,下面一一介绍并且分析复杂度。 第一种做法比较容易想到,就是有点类似于MergeSort的思路,就是分治法,不了解MergeSort的朋友,请参见归并排序-维基百科,是一个比较经典的O(nlogn)的排序算法,还是比较重要的。思路是先分成两个子任务,然后递归求子任务,最后回溯回来。这个题目也是这样,先把k个list分成两半,然后继续划分,知道剩下两个list就合并起来,合并时会用到Merge Two Sorted Lists这道题,不熟悉的朋友可以复习一下。代码如下:
/*
SOL 1:
使用merge sort和分治法完成
*/
public ListNode mergeKLists1(List<ListNode> lists) {
// 记得加上这个合法性判断。
if (lists == null || lists.size() == 0) {
return null;
} return helper(lists, 0, lists.size() - 1);
} /*
l, r表示list的左右边界
*/
public ListNode helper(List<ListNode> lists, int l, int r) {
if (l < r) {
int mid = l + (r - l) / 2; /*
分治法。把问题分为2个更小的子问题:左边list的merge,和右边list的merge.
再把2个生成的解合并在一起。
*/
return merge(helper(lists, l, mid), helper(lists, mid + 1, r));
} return lists.get(l);
} public ListNode merge(ListNode n1, ListNode n2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy; while (n1 != null && n2 != null) {
if (n1.val < n2.val) {
cur.next = n1;
n1 = n1.next;
} else {
cur.next = n2;
n2 = n2.next;
} cur = cur.next;
} if (n1 != null) {
cur.next = n1;
} else {
cur.next = n2;
} return dummy.next;
}
我们来分析一下上述算法的时间复杂度。假设总共有k个list,每个list的最大长度是n,那么运行时间满足递推式T(k) = 2T(k/2)+O(n*k)。根据主定理,可以算出算法的总复杂度是O(nklogk)。如果不了解主定理的朋友,可以参见主定理-维基百科。空间复杂度的话是递归栈的大小O(logk)。
SOLUTION 2:
接 下来我们来看第二种方法。这种方法用到了堆的数据结构,思路比较难想到,但是其实原理比较简单。维护一个大小为k的堆,每次取堆顶的最小元素放到结果中, 然后读取该元素的下一个元素放入堆中,重新维护好。因为每个链表是有序的,每次又是去当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元 素按从小到大放在结果链表中。这个算法每个元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是 O(nklogk)。空间复杂度是堆的大小,即为O(k)。代码如下:
/*
SOL 2:
使用 priority Queue.
*/
public ListNode mergeKLists(List<ListNode> lists) {
// 记得加上这个合法性判断。
if (lists == null || lists.size() == 0) {
return null;
} int size = lists.size(); PriorityQueue<ListNode> q = new PriorityQueue<ListNode>(size,
new Comparator<ListNode>() {
// 注意,此处参数用ListNode
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
}
); // Add all the head node to the priority queue.
for (ListNode node: lists) {
if (node != null) {
// Should skip the null node.s
q.offer(node);
}
} ListNode dummy = new ListNode(0);
ListNode tail = dummy; while (!q.isEmpty()) {
// get the smallest node from the queue.
ListNode cur = q.poll(); tail.next = cur;
tail = tail.next; // 将下一个节点补充进来。
if (cur.next != null) {
q.offer(cur.next);
}
} return dummy.next;
}
GITHUB:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/list/MergeKLists_1204.java
LeetCode: Merge k Sorted Lists 解题报告的更多相关文章
- 【原创】leetCodeOj --- Merge k Sorted Lists 解题报告
题目地址: https://oj.leetcode.com/problems/merge-k-sorted-lists/ 题目内容: /** * Definition for singly-linke ...
- LeetCode: Merge Two Sorted Lists 解题报告
Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list shoul ...
- LeetCode Merge k Sorted Lists 解决报告
https://oj.leetcode.com/problems/merge-k-sorted-lists/ 归并K已经整理阵列,和分析算法的复杂. 解决报告:无论是不考虑优化,最简单的实现是要重新走 ...
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...
- leetcode -- Merge k Sorted Lists add code
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [ ...
- LeetCode:Merge k Sorted Lists
题目链接 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...
- LeetCode——Merge k Sorted Lists
Discription: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its ...
- LeetCode Merge k Sorted Lists (链表)
题意 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...
- [Leetcode] Merge k sorted lists 合并k个已排序的链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思 ...
随机推荐
- SIGTERM等信号含义【转】
主要是做sigterm 和sigkill区别的比较,之前的好多操作,在结束正在运行的一个程序的时候,常用kill,这个以后的注意,在sigterm不起作用的时候,再使用kill; 原文地址:http: ...
- IT编年史 技术生命周期起步,成长,成熟和衰退四个阶段 IT历史总结
IT编年史 最近查看了大量的正史或者野史,体会了整个IT夜发展的风气云涌,颇为激动,撰写如下. 感谢google黑板报的浪潮之巅http://googlechinablog.com/2007/07/a ...
- 【Spring】Spring之向 IOC 容器注入对象的三种方式
关于Spring的搭建可参见:浅析Spring框架的搭建.在测试之前还是应该先将环境配置好,将相关Jar包导进来.Spring创建的对象,默认情况下都是单例模式,除非通过scope指定. 向IOC容器 ...
- 【Oracle】Oracle的内外连接
目录结构: contents structure [+] Oracle的内外连接 内连接 等值连接 非等值连接 自连接 外连接 外连接的特点 如何实现外连接 SQL99的内外连接 SQL99的内连接 ...
- 【Servlet】web.xml中url-pattern的用法
目录结构: contents structure [+] url-pattern的三种写法 servlet匹配原则 filter匹配原则 语法错误的后果 参考文章 一.url-pattern的三种写法 ...
- C# 进制转换(二进制、十六进制、十进制互转)
原文地址:https://www.cnblogs.com/icebutterfly/p/8884023.html C# 进制转换(二进制.十六进制.十进制互转)由于二进制数在C#中无法直接表示,所以所 ...
- 我所经历的企业中IT部门在企业内部的地位
本月参加了一个ITIL的培训,从培训中了解很多关于企业信息化及系统业务运维的知识和方法论.通过这次培训并结合自己近6年的IT 工作经历,明白了以前很多不明白的道理. 先说说自己经历的几家公司吧,我属于 ...
- SQL如何获得本季度第一天、一年的第一天、本月的最后一天
nterval 参数,具有以下设定值: 设置 描述 Year yy, yyyy 年 quarter qq, q 季 Month mm, m 月 dayofyear dy, y 一年的日数 Day dd ...
- numpy 数组迭代Iterating over arrays
在numpy 1.6中引入的迭代器对象nditer提供了许多灵活的方式来以系统的方式访问一个或多个数组的所有元素. 1 单数组迭代 该部分位于numpy-ref-1.14.5第1.15 部分Singl ...
- Linux中断概述
中断和异常 1.1中断的由来及实质 Linux内核要管理计算机上的硬件设备,首先要和他们通信.而处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器向硬件发出一个请求,然后 ...