LeetCode21、合并两个有序链表

64 阅读2分钟

LeetCode 系列记录我学习算法的过程。

持续创作,加速成长!这是我参与「掘金日新计划 6 月更文挑战」的第 20 天,点击查看活动详情

题目

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

示例:

image.png

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

提示

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

思路

给定的两个链表均是升序的,那解起来其实就很简单了

  • 如果两个链表有为空的,直接返回不为空的链表即可
  • 定义头尾两个指针,判断两个链表头结点大小,然后初始化头尾指针为较小项的结点
  • 遍历两个链表,结束条件为其中一个链表遍历完
  • 判断两个链表当前结点大小,将尾指针指向较小项,并移动较小项链表
  • 将尾指针指向下一项,然后将下一项置空
  • 最后将尾指针指向未遍历完的链表
  • 返回头指针

代码实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function(list1, list2) {
    // 如果两个链表有为空的,则直接返回不为空的链表即可
    if(!list1 || !list2) return list1 || list2
    // 头指针和尾指针
    let head = null, next = null
    // 判断 list1 和 list2 头结点的大小,初始化头尾指针
    if(list1.val < list2.val) {
        head = next = list1
        list1 = list1.next
    } else {
        head = next = list2
        list2 = list2.next
    }
    // 当两个链表遍历完某一个时结束循环
    while(list1 && list2) {
        // 将尾指针指向较小的一项,并移动较小项的指针
        if(list1.val < list2.val) {
            next.next = list1
            list1 = list1.next
        } else {
            next.next = list2
            list2 = list2.next
        }
        // 将尾指针指向下一项
        next = next.next
        // 将尾指针下一项置空
        next.next = null
    }
    // 将尾指针下一项指向未遍历完的链表
    next.next = (list1 || list2)
    // 返回头指针
    return head
};

优化

没想到还可以用递归的方式来实现,而且代码简洁了很多

既然 mergeTwoLists 这个方法是将两个链表进行升序合并,那我们就可以先找下较小项的链表

然后将该链表的下一项设置为 mergeTwoLists 该链表后续及另一链表的结果

/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function(list1, list2) {
    // 如果有链表为空 返回不为空的链表
    if (!list1 || !list2) return list1 || list2
    if (list1.val < list2.val) {
        // 递归实现链表合并
        list1.next = mergeTwoLists(list1.next, list2)
        return list1
    } else {
        list2.next = mergeTwoLists(list2.next, list1)
        return list2
    }
};