【LeetCode】23.合并K个排序链表
题目描述
合并k个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
题目解析
方法一:暴力法
解题思路
合并K个排序链表,首先我们直接采用暴力法去解决,将链表所有节点的val值放入一个List中,然后将这个List进行排序,根据排序后的List重新构建新链表。
代码示例
Java:
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
// 1. 将链表节点放入一个List中
List<Integer> arr = new ArrayList<Integer>();
for (int i = 0; i < lists.length; i++) {
ListNode cur = lists[i];
while(cur != null) {
arr.add(cur.val);
cur = cur.next;
}
}
// 2. 排序
Collections.sort(arr);
// 3. 重新构建链表
ListNode res = new ListNode(0);
ListNode cur = res;
for(int i = 0; i < arr.size(); i++) {
ListNode node = new ListNode(arr.get(i));
cur.next = node;
cur = cur.next;
}
return res.next;
}
}
复杂度分析
时间复杂度:O(N * log(N)), N代表所有链表节点数量。
- 遍历所有值需要花费O(N)时间
- 稳定的排序算法花费N * log(N)时间
- 重新构建链表需要花N * log(N)时间
空间复杂度:O(N)
方法二:堆排序法
解题思路
采用堆的方式来进行链表节点的排序,创建一个大小为K的小根堆,首先将K个链表的头指针插入到堆中,然后取出堆顶元素,同时将堆顶元素的下一个节点插入到最小堆中,然后循环该操作直至链表节点全部遍历完成。
代码示例
Java:
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
// 1. 初始化小根堆
PriorityQueue<ListNode> queue = new PriorityQueue(new Comparator<ListNode>() {
public int compare(ListNode o1, ListNode o2) {
return (o1.val - o2.val);
}
});
for(int i = 0; i < lists.length; i++) {
if (lists[i] != null) queue.add(lists[i]);
}
// 2. 取出堆顶元素,并将堆顶元素的下一节点插入小根堆
ListNode res = new ListNode(0);
ListNode cur = res;
while(!queue.isEmpty()) {
ListNode top = queue.poll();
if (top.next != null) {
queue.add(top.next);
}
cur.next = top;
cur = cur.next;
}
return res.next;
}
}
复杂度分析
时间复杂度:O(N * log(K)),N代表所有链表节点数量,K代表链表的个数。
空间复杂度:O(K)
方法三:分治法
解题思路
我们将K个链表对半划分,先合并前K/2个链表,再合并后K/2个链表,然后将前K/2个链表合并成的链表再与后K/2个链表合并的链表进行合并,得到最终结果。
在处理前K/2个和后K/2个链表时,就跟上述方法思路一致,通过递归的方式不停的将链表进行划分,直到链表无法继续划分为止,将链表返回给递归的上一层进行两两合并。
分治思路:划分子问题 --> 合并子问题结果【递归实现】
代码示例
Java:
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
return divide(lists, 0, lists.length-1);
}
public ListNode divide(ListNode[] lists, int lo, int hi) {
if (lo == hi) return lists[lo];
int mid = lo + (hi - lo) / 2;
ListNode left = divide(lists, lo, mid);
ListNode right = divide(lists, mid + 1, hi);
return merge(left, right);
}
public ListNode merge(ListNode l1, ListNode l2) {
if(l1 == null || l2 == null) {
return (l1 == null) ? l2 : l1;
}
if(l1.val <= l2.val) {
l1.next = merge(l1.next,l2);
return l1;
} else {
l2.next = merge(l1, l2.next);
return l2;
}
}
}
复杂度分析
时间复杂度:O(N * log(K)),N代表所有链表节点数量,K代表链表的个数。
空间复杂度:O(K)
【LeetCode】23.合并K个排序链表的更多相关文章
- LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)
23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...
- Java实现 LeetCode 23 合并K个排序链表
23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输 ...
- [LeetCode]23. 合并K个排序链表(优先队列;分治待做)
题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1 ...
- [LeetCode] 23. 合并K个排序链表
题目链接: https://leetcode-cn.com/problems/merge-k-sorted-lists/ 题目描述: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂 ...
- leetcode 23. 合并K个排序链表 JAVA
题目: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: ...
- LeetCode 23. 合并K个排序链表(Merge k Sorted Lists)
题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: ...
- LeetCode 23 ——合并 K 个排序链表
1. 题目 2. 解答 2.1. 方法一 在 合并两个有序链表 的基础上,我们很容易想到第一种解法,首先我们将第一个链表和第二个链表合并成一个新的链表,然后再往后依次合并接下来的每个链表即可. 假设每 ...
- LeetCode题解-23 合并K个排序链表 Hard
合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1-&g ...
- Leetcode题库——23.合并k个排序链表
@author: ZZQ @software: PyCharm @file: mergeKLists.py @time: 2018/10/12 19:55 说明:合并 k 个排序链表,返回合并后的排序 ...
随机推荐
- Error while importing sbt project:--创建sbt项目导入文件出错
错误截图如下: Error while importing sbt project: List([info] Loading global plugins from C:\Users\RYJ\.sbt ...
- C 2015年真题【保】
1.编写一个完整的程序,使之能完成以下功能:从键盘中输入若干个整数,用链表储存这些输入的数,并要求存储的顺序与输入的顺序相反. 分析:链表建立[头插法] 代码: #include <stdio. ...
- 树莓派4B踩坑指南 - (13)用samba建立家庭局域网共享中心
树莓派在家中至少三个作用:家庭资源共享中心.无线打印服务器.下载服务器. 家庭资源共享中心用samba实现家庭局域网共享,树莓派4B的话可以接2个3.0的移动硬盘. 实测速度不快,Win读2Mb/s写 ...
- nmap端口扫描工具安装和使用方法
nmap(Network Mapper)是一款开源免费的针对大型网络的端口扫描工具,nmap可以检测目标主机是否在线.主机端口开放情况.检测主机运行的服务类型及版本信息.检测操作系统与设备类型等信息. ...
- 【笔记3-27】Python语言基础
流程控制语句 if语句 input() if-else if-elif-else
- 10行Python代码实现目标检测
要知道图像中的目标是什么? 或者你想数一幅图里有多少个苹果? 在本文中,我将向你展示如何使用Python在不到10行代码中创建自己的目标检测程序. 如果尚未安装python库,你需要安装以下pytho ...
- Thread --三大特性 原子性,可见性,有序性
原子性.可见性.有序性 什么是原子性 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行. 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元, ...
- iOS 图片加载和处理
一.图片显示 图片的显示分为三步:加载.解码.渲染.解码和渲染是由 UIKit 进行,通常我们操作的只有加载. 以 UIImageView 为例.当其显示在屏幕上时,需要 UIImage 作为数据源. ...
- Kitty-Cloud环境准备
项目地址 https://github.com/yinjihuan/kitty-cloud 开发工具 开发工具目前对应的都是我本机的一些工具,大家可以根据自己平时的习惯选择对应的工具即可. 工具 说明 ...
- 20175314 《Java程序设计》第十周学习总结
20175314 <Java程序设计>第十周学习总结 教材学习内容总结 进程与线程:一个进程的进行期间可以产生多个线程. Java内置对多线程的支持,计算机只能执行线程中的一个,Java虚 ...