将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入: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
解法二
递归 参考力扣官方答案,有如下的分析:
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 # 返回最后的结果
复杂度分析
- 时间复杂度:。
- 空间复杂度:解法一的空间复杂度为:,解法二的空间复杂度为:。