[LeetCode题解]23. 合并K个升序链表 | 分治 + 递归
方法一:分治 + 递归
解题思路
在21. 合并两个有序链表,我们知道如何合并两个有序链表。而本题是合并 k
个有序链表,可以通过大问题拆分成小问题解决,即把 k
个链表,拆分成 k/2
个链表组,俩俩合并,直到合并成一个链表,这就是分而治之的思想。
可以通过递归来实现分治算法:
- 定义函数功能:合并链表数组中的
left
到right
个链表 - 结束条件:
left == right
,即只剩下一个链表,无须合并,直接返回 - 递推公式:将
[left, right]
拆分成两半,分别获得左边已合并的链表l1
和右边已合并的链表l2
,然后再对这两个链表进行合并。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode MergeKLists(ListNode[] lists) {
if(lists == null || lists.Length == 0) {
return null;
}
return MergeKLists(lists, 0, lists.Length-1);
}
private ListNode MergeKLists(ListNode[] lists, int left, int right) {
if(left == right) {
return lists[left];
}
int mid = left + (right-left)/2;
ListNode l1 = MergeKLists(lists, left, mid);
ListNode l2 = MergeKLists(lists, mid+1, right);
return MergeTwoLists(l1, l2);
}
private ListNode MergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null) {
return l2;
}
if(l2 == null) {
return l1;
}
ListNode dummy = new ListNode();
ListNode p1 = l1, p2 = l2, cur = dummy;
while(p1 != null && p2 != null) {
if(p1.val < p2.val) {
cur.next = p1;
cur = cur.next;
p1 = p1.next;
} else {
cur.next = p2;
cur = cur.next;
p2 = p2.next;
}
}
cur.next = p1 == null ? p2 : p1;
return dummy.next;
}
}
复杂度分析
- 时间复杂度:\(O(n*k*logk)\),其中链表数组长度为 \(k\),链表的平均长度为 \(n\)。函数
MergeKLists
的时间复杂度为 \(O(klogk)\)(分治),函数MergeTwoLists
的时间复杂度是 \(O(n)\),因此总的时间复杂度为 \(O(n*k*logk)\)。 - 空间复杂度:\(O(logk)\),递归会使用到 \(O(logk)\) 空间代价的栈空间。
[LeetCode题解]23. 合并K个升序链表 | 分治 + 递归的更多相关文章
- LeetCode题解-23 合并K个排序链表 Hard
合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1-&g ...
- 【LeetCode】23.合并K个排序链表
题目描述 23.合并K个排序链表 合并k个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] ...
- 23. 合并K个排序链表 分治
这种k个相同的子问题,可以两两分治,总的运算次数为logk 关键部分 int dis=1; int len=lists.size(); while(dis<=len) { for(int i=0 ...
- 浅谈归并排序:合并 K 个升序链表的归并解法
在面试中遇到了这道题:如何实现多个升序链表的合并.这是 LeetCode 上的一道原题,题目具体如下: 用归并实现合并 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个排序链表
@author: ZZQ @software: PyCharm @file: mergeKLists.py @time: 2018/10/12 19:55 说明:合并 k 个排序链表,返回合并后的排序 ...
随机推荐
- centos8平台搭建mysql8数据库主从同步
一,两台服务器的规划 a服务器:主机名:yjweb ip: 121.122.123.47 角色:主库 server-id:1 j服务器:主机名: os3 ip: 121.122.123.134 角色: ...
- flutter_bloc使用解析---骚年,你还在手搭bloc吗!
前言 首先,有很多的文章在说flutter bloc模式的应用,但是百分之八九十的文章都是在说,使用StreamController+StreamBuilder搭建bloc,提升性能的会加上Inher ...
- WebSocket的理解
Websocket相对于无状态的HTTp协议,是在一次成功连接之后,在关闭请求之前,服务器和客户端能顺利进行信息传输.而不用像HTTP那样每一次都要告诉服务器这个请求者是谁(身份鉴别信息). 在HTT ...
- Fur 是 .NET 5 平台下企业应用开发最佳实践框架。
Fur 是 .NET 5 平台下企业应用开发最佳实践框架. 立即尝鲜 Fur 是基于最新的 .NET 5 RC2 构建,目的是为了尽早体验新功能,对即将到来的 .NET 5 正式版做出最快的响应. 所 ...
- (静默安装)Cent OS 6_5(x86_64)下安装Oracle 11g
Cent OS 6_5(x86_64)下安装Oracle 11g 1 硬件要求 1.1 内存 & swap 物理内存不少于1G 硬盘可以空间不少于5G swap分区空间不少于2G Mini ...
- Github优质库分享-01算法小抄 基于LeetCode
Github 优质库分享-01 算法小抄 该库总共 60 多篇原创文章,都是基于 LeetCode 的题目,涵盖了所有题型和技巧,而且一定要做到举一反三,通俗易懂,绝不是简单的代码堆砌. 目前 sta ...
- dcoker 搭建单节点redis
1.安装docker 1.检查内核版本,必须是3.10及以上 [root@localhost ~]# uname -r 2.安装docker [root@localhost ~]# yum insta ...
- pip intsall 遇到的各种问题
一.pip install 安装指定版本的包 要用pip 安装指定版本的python的包,只需要通过 == 操作符指定. pip install robotframework == 2.8.7 将安装 ...
- BCVP,想真正为社区做努力的开发者们
基于Net/Core,快速搭建 API & SPA 及微服务应用组织 BASE NETCORE (VUE) PROJECT TEAM 每一个.NET开发者都可以通过自己的开源项目(最好可以配套 ...
- GPRS DTU的工作原理和应用场景有哪些
GPRS DTU是属于物联网无线数据终端设备的中一种,它主要是利用公用运营商的GPRS网络(又称G网)来为用户提供无线长距离数据传输的功能.一般都是采用的高性能工业级8/16/32位通信处理器和工业级 ...