LeetCode_21_简单_合并两个有序链表


1. 题目

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

示例 1:

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

示例 2:

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

示例 3:

输入: l 1 = [ ] , l 2 = [ 0 ] l1 = [], l2 = [0] l1=[],l2=[0]
输出: [ 0 ] [0] [0]


提示

  • 两个链表的节点数目范围是 [ 0 , 50 ] [0, 50] [0,50]
  • 100 ≤ N o d e . v a l ≤ 100 100 \leq Node.val \leq 100 100Node.val100
  • l 1 l1 l1 l 2 l2 l2 均按 非递减顺序 排列

2. 思路及代码实现(Python)

2.1 递归

可以通过递归的方式,不断地取出值较小的节点,并将该较小值节点指向后续链表和另一个链表得合并链表,不断地堆栈,直到到达边界条件,即最后一个节点指向 N o n e None None。用列表得形式直观地表示如下:

{ l i s t 1 [ 0 ] + m e r g e ( l i s t 1 [ 1 : ] , l i s t 2 ) l i s t 1 [ 0 ] < l i s t 2 [ 0 ] l i s t 2 [ 0 ] + m e r g e ( l i s t 1 , l i s t 2 [ 1 : ] ) o t h e r w i s e \left.\left\{\begin{array}{ll}list1[0]+merge(list1[1:],list2)&list1[0]<list2[0]\\list2[0]+merge(list1,list2[1:])&otherwise\end{array}\right.\right. {list1[0]+merge(list1[1:],list2)list2[0]+merge(list1,list2[1:])list1[0]<list2[0]otherwise

每次进行合并时,会取出两个链表地头节点,直到至少一个链表为空,在最差情况下,调用次数为两个链表长度之和 ( m + n ) (m+n) (m+n),即时间复杂度为 O ( m + n ) O(m+n) O(m+n),空间复杂度为为栈深,每调用一次栈深加一,因此空间复杂度也为 O ( m + n ) O(m+n) O(m+n)

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

执行用时:43 ms
消耗内存:16.43 MB

2.2 迭代

前面的方式是用递归的方式,把除了取出的头节点之外的链表的合并,归纳为一个合并函数,不断去调用直至边界条件,实现链表的合并。如果不把合并的操作定义为函数反复自调,那其实就是迭代的思路。

这里我们可以设定一个哨兵节点 p r e h e a d prehead prehead ,该节点相当于另起一条链表,但最后返回结果的时候可以不包含该哨兵节点,该链表方便我们得到合并后的结果。通过维护一个 p r e v prev prev 指针,不断地调整该指针指向两个链表中值较小的头节点,不断迭代直至某个链表指向空节点,当 p r e v prev prev 指向某链表的头节点之后,该链表的头节点需更新为下一个节点。如果最后某链表为空,另外的链表还有剩余,则将剩余部分直接接到 p r e v prev prev 指针后面。

同样的,迭代次数在最差情况下为 ( m + n ) (m+n) (m+n) 次,时间复杂度为 O ( m + n ) O(m+n) O(m+n),但由于我们只维护一个指针,此时的空间复杂度为 O ( 1 ) O(1) O(1)

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        prehead = ListNode(-1)
        prev = prehead
        while l1 and l2:
            if l1.val <= l2.val:
                prev.next = l1
                l1 = l1.next
            else:
                prev.next = l2
                l2 = l2.next            
            prev = prev.next
        prev.next = l1 if l1 is not None else l2
        return prehead.next

执行用时:34 ms
消耗内存:16.38 MB

题解来源:力扣官方题解

  • 26
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值