题目地址
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列
哑节点
创建 哑节点 作为 结果链表 的开头,返回结果是这个节点的下一个位置。目的是:在未遍历之前,我们不知道构建的结果中,开头元素到底是 l1 还是 l2, 为了让代码整齐,创建哑节点。
使用 move 游标
哑节点标记了 结果链表 的开头,因此是不能移动的。为了把两个链表 merge 的结果放到结果链表的最后,就需要使用一个 move 游标指向 结果链表 的最后一个元素。初始时,move 指向 哑节点,之后随着结果链表的增加而不停地向后移动,始终保持其指向 结果链表 的最后一个元素。
代码实现:
解法一(推荐):
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
# 创建哑节点作为 结果链表 的开头
dummy = ListNode(0)
# 有个游标,标识 结果链表 的结尾
move = dummy
# l1 和 l2 都未遍历结束
while l1 and l2:
# 如果 l1 的数值比较小
if l1.val <= l2.val:
# 把 l1 头部节点拼接到 结果链表 的结尾
move.next = l1
# l1 指向下一个节点
l1 = l1.next
else:
# 把 l2 头部节点拼接到 结果链表 的结尾
move.next = l2
# l2 指向下一个节点
l2 = l2.next
# 移动 结果链表 的结尾指针
move = move.next
# l1 或者 l2 尚未使用完,拼接到 结果链表 的最后
if l1:
move.next = l1
if l2:
move.next = l2
#move.next = l1 if l1 else l2
# 返回哑节点的下一个位置
return dummy.next
解法二(递归):
不推荐这个解法是因为递归没那么容易理解,就算看懂了,下次换别的题,还是不会写递归。
重点是!!这个时间和空间复杂度都超级差!!!
参考地址
里面有个动画,比较清晰
终止条件:当两个链表都为空时,表示我们对链表已合并完成。
如何递归:我们判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。(调用递归)
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1: return l2 # 终止条件,直到两个链表都空
if not l2: return l1
if l1.val <= l2.val: # 递归调用
l1.next = self.mergeTwoLists(l1.next,l2)
print('l1',l1)
return l1
else:
l2.next = self.mergeTwoLists(l1,l2.next)
print('l2',l2)
return l2
print的过程(以示例1为例):
l1 ListNode{val: 4, next: ListNode{val: 4, next: None}}
l2 ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 4, next: None}}}
l1 ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 4, next: None}}}}
l2 ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 4, next: None}}}}}
l1 ListNode{val: 1, next: ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 4, next: None}}}}}}