21. 合并两个有序链表

145 阅读2分钟

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

示例 1:

image.png

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

解法一

看答案之前自己的写法,主要思想是:每次比较l1和l2的当前节点的val,谁小就将该节点放到新的链表中,并且指向下一个节点。再继续比较后面的两个节点。

def mergeTwoLists1(l1, l2):
    dummy = ListNode()  # 哑节点
    l = None
    while l1 or l2:

        # 特殊讨论,当有一个链表为空的情况
        if l is None and l1 is None and not l2 is None:
            return l2
        elif l is None and not l1 is None and l2 is None:
            return l1

        # l2 还有剩下的节点
        if l1 is None and not l2 is None:
            l.next = l2
            break
        elif not l1 is None and l2 is None:
            l.next = l1
            break
        else:
            tmp = ListNode()

            if l1.val < l2.val:
                tmp.val = l1.val
                l1 = l1.next
            else:
                tmp.val = l2.val
                l2 = l2.next

            if l is None:
                l = tmp
                dummy.next = l
            else:
                l.next = tmp
                l = l.next

    return dummy.next

力扣官方的做法也是用的思想,只是代码更加简洁:

def mergeTwoLists3(l1, l2):
    """迭代"""
    prehead = ListNode(-1)  # 相当于定义一个哑节点
    prev = prehead  # 定义一个指针指向哑节点

    # l1 和 l2 都还有节点,才走下面的循环
    while l1 and l2:
        if l1.val < l2.val:  # 如果l1.val < l2.val,那么就指向l1
            prev.next = l1
            l1 = l1.next
        else:
            prev.next = l2
            l2 = l2.next
        prev = prev.next  # 将指针指向新的比较过的节点

    # 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
    prev.next = l1 if l1 is not None else l2

    return prehead.next

解法二

递归 参考力扣官方答案,有如下的分析:

截屏2021-04-16 下午5.45.33.png

def mergeTwoLists2(l1, l2):
    """递归解法"""
    if l1 is None:
        return l2  # 出口
    elif l2 is None:
        return l1  # 出口
    elif l1.val < l2.val:
        # 如果l1.val < l2.val,那么l1.next节点就是mergeTwoLists2(l1.next, l2)的结果的节点
        l1.next = mergeTwoLists2(l1.next, l2)
        return l1  # 返回最后的结果
    else:
        l2.next = mergeTwoLists2(l1, l2.next)
        return l2  # 返回最后的结果
复杂度分析
  • 时间复杂度:O(n+m)O(n+m)
  • 空间复杂度:解法一的空间复杂度为:O(1)O(1),解法二的空间复杂度为:O(n+m)O(n+m)

力扣官方答案