Time:2019/4/10
Title: Merge K Sorted Lists
Difficulty: Difficulty
Author: 小鹿
题目:Merge K Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
兼并
k 个排序链表,返回兼并后的排序链表。请剖析和形貌算法的庞杂度。
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
Solve:
▉ 算法思绪
假如我们完成了简朴的基于两个单链表的兼并以后,关于这个题来讲,考核点是分治算法,我以为另有一个考核点就是递归挪用,分治的同时经常常运用递返来处理。
1、本道题能够借助合并排序的头脑,略加革新就能够处理。
2、将数组中的链表分治,就是不停的将数组中的链表中心离别,离别兼并,然后团体兼并成一个大链表。
▉ 代码完成
/**
* @param {number[]} nums
* @return {number[]}
* 功用:兼并 k 个链表
* 边界前提:
* 1)推断数组是不是为空
* 2)推断数组长度为 1 时
* 3)推断数组长度为 2 时
* 4)推断数组长度大于 2 时
*/
var mergeKLists = function(lists) {
// 当 lists 中有一个链表时
if(lists.length == 0){
return null;
}else if(lists.length == 1){
// 推断数组长度为 1 时
return lists[0];
}else if(lists.length == 2){
// 推断数组长度为 2 时
return mergeTwoLists(lists[0],lists[1]);
}else{
// 推断数组长度大于 2 时
// 取数组的中部坐标
let middle = Math.floor(lists.length/2);
// 取摆布双方数组
let leftList = lists.slice(0,middle);
let rightList = lists.slice(middle);
// 递归、支解、兼并
return mergeTwoLists(mergeKLists(leftList),mergeKLists(rightList));
}
};
//两个链表兼并
var mergeTwoLists = function(l1, l2) {
let result = null;
//停止前提
if(l1 == null) return l2;
if(l2 == null) return l1;
//推断数值大小递归
if(l1.val < l2.val){
result = l1;
result.next = mergeTwoLists(l1.next,l2);
}else{
result = l2;
result.next = mergeTwoLists(l2.next,l1);
}
//返回结果
return result;
};
▉ 扩大:分治算法
分治算法常常和递归一块运用,所谓分治算法,望文生义,分而治之,最基本的分之算法在合并排序、疾速排序都有用到。也就是将原题目离别成 n 个范围较小,而且构造与原题目类似的子题目,递归地处理这些子题目,然后再兼并其结果,就获得原题目的解。
1、分治算法递归每层操纵
- 剖析:将原题目剖析成一系列的子题目。
- 处理:递归地求解各个子题目,若子题目充足小,则直接求解;
- 兼并:将子题目的结果兼并成原题目。
2、分治算法满足的前提
- 可剖析:原题目与剖析成的小题目具有雷同的形式;
- 无关联:原题目剖析成的子题目能够自力求解,子题目之间没有相关性,这一点是分治算法跟动态计划的显著区分。
- 停止前提:具有剖析停止前提;
- 兼并不能太庞杂:能够将子题目兼并成原题目,而这个兼并操纵的庞杂度不能太高,不然就起不到减小算法整体庞杂度的结果了。
迎接一同加入到 LeetCode 开源 Github 堆栈,能够向 me 提交您其他言语的代码。在堆栈上对峙和小伙伴们一同打卡,配合完美我们的开源小堆栈!
Github:https://github.com/luxiangqia…