LeetCode 21:合并两个有序链表

175 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

LeetCode 21:合并两个有序链表

题目描述

题目描述:

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

解题思路

思路一:递归

思路如下:

  1. 判断 list1 和 list2 哪一个链表的头节点的值更小;
  2. 然后递归地决定下一个添加到结果里的节点;
  3. 如果两个链表有一个为空,递归结束; 即递归的终止条件
var mergeTwoLists = function (list1, list2) {
  if (list1 === null) {
    return list2;
  } else if (list2 === null) {
    return list1;
  } else if (list1.val < list2.val) {
    list1.next = mergeTwoLists(list1.next, list2);
    return list1;
  } else {
    list2.next = mergeTwoLists(list1, list2.next);
    return list2;
  }
};

时间复杂度: O(n+m)  ,其中 n 和 m 分别为两个链表的长度

空间复杂度: O(n+m),其中 n 和 m 分别为两个链表的长度

思路二:迭代

需要一个dummy node(哑节点)指向链表的头节点,便于返回链表的头部。

当 list1 和 list2 都不是空链表时,判断 list1 和 list2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。
如果有未合并完的,直接将链表末尾指向未合并完的链表即可;
最后返回dummy.next即可。
实现代码如下:

/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function (list1, list2) {
  let curr = new ListNode();
  let dummy = curr;
  while (list1 != null && list2 != null) {
    if (list1.val < list2.val) {
      curr.next = list1;
      list1 = list1.next;
    } else {
      curr.next = list2;
      list2 = list2.next;
    }
    curr = curr.next;
  }
  // 有未合并完的,直接将链表末尾指向未合并完的链表即可
  curr.next = list1 === null ? list2 : list1;
  return dummy.next;
};

时间复杂度: O(n+m)  ,其中 n 和 m 分别为两个链表的长度

空间复杂度: O(1);

参考资料

21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)