算法基础~链表~排序链表的合并(k条)
算法基础~链表~排序链表的合并(k条)
1,题意:已知k个已排序链表头结点指针,将这k个链表合并,合并后仍然为有序的,返回合并后的头结点。
2,方法之间时间复杂度的比较:
方法1(借助工具vector封装好的sort方法):将k * n个结点放到vector,则原 vector的排序时间复杂度是 O(nlogn);
有k*n个结点的排序,时间复杂度是 O(knlog(kn));
方法2(分制后相连法),分制:这里咱要想到高中的DNA复制~一个DNA复制生成K个DNA的过程。
【1----复制----》k个数】,复制了n次,结果有k个数,则2n = k。
这里咱反过来,想到是在融合,则【k个数----复制----》1】,这个过程需要融合的次数,跟当初 复制次数一样,由2n = k,解得,n=logk。
●具体过程分析:
第一次,链表两两之间合并,进行 合并次数为 k/2,每次处理结点数字为2n个;
第二次,链表两两之间合并,进行 合并次数为 k/4,每次处理结点数字为4n个;
。。。
由上面推导的融合过程,知道最后一次,即 第 logk 次,链表两两之间进行 合并,进行合并次数为
k/2 logk,每次处理结点数字为2 logk n个;
时间复杂度:2n * k/2 + 4n * k/4 + 8n * k/8 + … + 2 logk n * k/2 logk = nk + nk + nk +… +nk = O(nklogk);
所以方法2,更优;
3,从方法2的分析过程,咱深深的感受到一种:把规模大的问题变成规模较小的;规模较小的问题又变成规模更小的问题,
小到一定程度可以直接得出它的解,从而得到问题的解。~没错,是递归的味道!
4,直接上代码,分析如上【代码中的mergeTwoLists(链表1头指针,链表2头指针)参考咱上一篇文章:
《算法基础~链表~排序链表的合并(2条)》~ https://www.cnblogs.com/shan333/p/15041561.html】:
public class Solution {
public:
ListNode* mergeKLists(std::vector<ListNode*>& lists){
if(lists.size() == 0){
return NULL;
}
if(lists.size() == 1){
return lists[0];
}
if(lists.size() == 2){
return mergeTwoLists(lists[0],lists[1]);
}
int mid = lists.size() / 2;
//拆分成两个子lists
std::vector<ListNode*> sub1_lists;
std::vector<ListNode*> sub2_lists;
for(int i = 0; i < mid; i++){
sub1_lists.push_back(lists[i]);
}
for(int i = mid; i < lists.size(); i++){
sub2_lists.push_back(lists[i]);
}
//递归,不断的两两链表进行融合
ListNode *l1 = mergeKList(sub1_lists);
ListNode *l2 = mergeKList(sub2_lists);
return mergeTwoLists(l1, l2);
}
}
5,递归思想的使用:
递归算法的思想是:把规模大的问题变成规模较小的;规模较小的问题又变成规模更小的问题,小到一定程度可以直接得出它的解,从而得到问题的解。
解决问题时,把一个问题转化为一个新的问题,而这个新的问题的解决方法仍与原问题的解法相同,
只是所处理的对象有所不同,这些被处理的对象之间是有规律的递增或递减;
参考文章:《什么情况下用递归?~https://blog.csdn.net/ggxxkkll/article/details/7524056》
算法基础~链表~排序链表的合并(k条)的更多相关文章
- 八大排序算法~简单选择排序【记录下标k变量的作用】
八大排序算法~简单选择排序[记录下标k变量的作用] 1,思想:打擂台法,数组中的前n-1个元素依次上擂台"装嫩",后边的元素一个挨着一个不服,一个一个上去换掉它 2,优化:通过记录 ...
- 代码题(14)— 合并有序链表、数组、合并K个排序链表
1.21. 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出 ...
- c语言:链表排序, 链表反转
下面将实现链表排序的排序和遍历显示功能: 所定义的链表结构如下: head -> p1 -> p2 ->p3 ->....->pn; head的本身不作为数据节点,hea ...
- [LeetCode] 23. 合并K个排序链表
题目链接: https://leetcode-cn.com/problems/merge-k-sorted-lists/ 题目描述: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂 ...
- [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 ...
- 合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1-&g ...
- 合并K个排序链表(java实现)
题目: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: ...
- 0008 合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1-&g ...
- 023合并K个链表并排序
#include "000库函数.h" struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), n ...
随机推荐
- P1045 [NOIP2003 普及组] 麦森数
题目描述 形如2^P−1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^P−1不一定也是素数. 到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377, ...
- 五、自定义Zabbix监控项目
要求: 沿用练习三,使用Zabbix实现自定义监控,实现以下目标:监控Linux服务器系统账户的数量. 方案: 需要使用Zabbix自定义key的方式实现自定义监控,参考如下操作步骤:1.创建自定义k ...
- CSS基础知识及其基本语法
一.什么是CSS CSS 是层叠样式表( Cascading Style Sheets ) 的简称. 有时我们也会称之为CSS 样式表或级联样式表. CSS 也是一种标记语言 CSS 主要用于设置HT ...
- UF_CSYS 坐标系操作
Open C UF_CSYS_ask_csys_info 获取WCS坐标系的原点坐标和矩阵标识UF_CSYS_ask_matrix_of_object 获得对象 ...
- 利用 Bean Validation 来简化接口请求参数校验
团队新来了个校招实习生静静,相互交流后发现竟然是我母校同实验室的小学妹,小学妹很热情地认下了我这个失散多年的大湿哥,后来... 小学妹:大湿哥,咱们项目里的 Controller 怎么都看不到参数校验 ...
- 学习响应式编程 Reactor (5) - reactor 转换类操作符(2)
Reactor 操作符 上篇文章我们将 Flux 和 Mono 的操作符分了 11 类,我们来继续学习转换类操作符的第 2 篇. 转换类操作符 转换类的操作符数量最多,平常过程中也是使用最频繁的. F ...
- moment常用方法
1.subtract方法,时间加减处理 console.log(moment().format("YYYY-MM-DD HH:mm:ss")); //当前时间 console.lo ...
- sql把一个字段中的特定字符替换成其他字符
将'0654879'替换成'0754879' UPDATE dbo.SG_Functionality SET FunctionalityCode=REPLACE(FunctionalityCode,' ...
- Java 读取Word表格中的文本和图片
本文通过Java程序来展示如何读取Word表格,包括读取表格中的文本和图片.下面是具体实现的步骤和方法. 1. 程序环境准备 代码编译工具:IntelliJ IDEA Jdk版本:1.8.0 测试文档 ...
- external-attacher源码分析(1)-main方法与启动参数分析
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...