「前端刷题」21. 合并两个有序链表

193 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

 

示例 1:

输入: l1 = [1,2,4], l2 = [1,3,4]

输出: [1,1,2,3,4,4]

示例 2:

输入: l1 = [], l2 = []

输出: []

示例 3:

输入: l1 = [], l2 = [0]

输出:[0]

 

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1l2 均按 非递减顺序 排列

解题思路

思路1

  • 标签:链表、递归
  • 这道题可以使用递归实现,新链表也不需要构造新节点,我们下面列举递归三个要素
  • 终止条件:两条链表分别名为 l1l2,当 l1 为空或 l2 为空时结束
  • 返回值:每一层调用都返回排序好的链表头
  • 本级递归内容:如果 l1val 值更小,则将 l1.next 与排序好的链表头相接,l2 同理
  • O(m+n)O(m+n)O(m+n),mmm 为 l1的长度,nnn 为 l2 的长度

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    if(l1 === null){
        return l2;
    }
    if(l2 === null){
        return l1;
    }
    if(l1.val < l2.val){
        l1.next = mergeTwoLists(l1.next, l2);
        return l1;
    }else{
        l2.next = mergeTwoLists(l1, l2.next);
        return l2;
    }
};

思路2

根据题意,我们知道我们的任务是要将两个升序链表合并为一个升序的新链表!

这就好比,军训的时候,有两个小组,每一组都是按照身高,从左往右依次站立的。

这时候,教官让我们两个小组,合并为一个小组,并且也要按照身高来站立。

这个时候,是不是感觉题目,有一点温度了,人间,又充满阳光了?

跟着你的感觉,我们来想象一下如何正确的合并成一个小组,流程如下:

  1. 首先,我们给小组命名,一组为 AAA,一组为 BBB,新组合的的 CCC 组。
  2. 对比 AAA 组和 BBB 组现在站在最前面的人的身高,矮的先出来,站在 CCC 组第一位。
  3. 然后再次对比两组开头的人的身高,矮的又站出来,站在 CCC 组第二位。
  4. 就这样周而复始,最终,ABABAB 两组的人,全部站到了 CCC 组,我们的任务也就完成了。

图解演示

代码

var mergeTwoLists = function(l1, l2) {
    if(!l1) return l2;
    if(!l2) return l1;
    if (l1.val < l2.val) {
        l1.next = mergeTwoLists(l1.next, l2);
        return l1;
    } else {
        l2.next = mergeTwoLists(l1, l2.next);
        return l2;
    }
};

最后

曾梦想仗剑走天涯

看一看世界的繁华

年少的心总有些轻狂

终究不过是个普通人

无怨无悔我走我路

「前端刷题」No.21