LeetCode 23 : 合并K个升序链表 - 归并+递归

210 阅读1分钟

给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

这一题和上次做的LeetCode 21有异曲同工之妙,其实21题是这一道题的子问题。

将21题解出后,我们可以知道如何合并两条升序链表。所以,这一题的问题就变成了,我们要怎样最快的将k条升序列表合并?按什么顺序合并?

这里我们用到的是归并:归并排序

然后可以用到在上次的题中已经封装好的mergeTwoLists函数,然后根据归并排序写一个mergeNode函数来决定每次合并的两条链表

var mergeKLists = function(lists) {
    if(!lists.length)return null;
    if(lists.length===1)return lists[0];
    
    return mergeNode(lists,0,lists.length-1);
};
var mergeNode = function(lists,start,end) {
    if(start==end){return lists[start];}
    var mid = Math.floor((end+start)/2);
    var l1 = mergeNode(lists,start,mid);
    var l2 = mergeNode(lists,mid+1,end);
    return mergeTwoLists(l1,l2);
};
function mergeTwoLists(l1,l2){
    if(l1===null){
        return l2;
    }else if(l2===null){
        return l1;
    }
    while(l1){
        if(l1.val<=l2.val){
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}

这是我做的第一道hard题,刚写的时候其实还挺怕的,但是一想,其实大多数的难的题目都是可以分解为几个小的子问题去解决的,所以只要自己耐心就好了。