LeetCode 之 JavaScript 解答第23题 —— 兼并K个有序链表(Merge K Sorted Lists)

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…

    原文作者:小鹿
    原文地址: https://segmentfault.com/a/1190000018839606
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞