# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
# # 方法1:
# # 搞一个新节点作为新链表,用来存放最后的答案
# # 比较list1, list2,每次将最小的那个放到新链表后面
# # 直到list1 or list2 为空,这样直接把剩下的不为空的给接到新链表后面
# dummy = ListNode(-1) # 新链表的头部
# current = dummy
# while list1 and list2:
# if list1.val < list2.val:
# current.next = list1
# list1 = list1.next
# else:
# current.next = list2
# list2 = list2.next
# current = current.next
# # 如果list1 or list2有一个遍历结束了
# if list1 == None:
# current.next = list2
# # else:
# elif list2 == None:
# current.next = list1
# return dummy.next
# # 方法2
# 方法1:
# 1. 首先检查两个链表是否为空,如果为空,则直接返回另一个链表。
# 2. 然后比较两个链表头节点的值,选择较小的那个作为合并后链表的头节点。
# 3. 使用一个循环来逐个比较两个链表的当前节点,将较小值的节点接到合并后的链表后面,并移动相应的指针。
# 4. 如果其中一个链表先遍历完成,将另一个链表的剩余部分直接连接到合并后的链表末尾。
# if list1 == None:
# return list2
# elif list2 == None:
# return list1
# elif list1.val < list2.val:
# small = list1
# else:
# small = list2
# current = small
# while list1 and list2:
# if list1.val < list2.val:
# # 把list1的值插入到current后面
# next_list1 = list1.next
# list1.next = current.next
# current.next = list1
# list1 = next_list1
# else:
# # 把list2的值插入到current后面
# next_list2 = list2.next
# list2.next = current.next
# current.next = list2
# list2 = next_list2
# current = current.next
# if list1 == None:
# current.next = list2
# elif list2 == None:
# current.next = list1
# return small
# 方法3:递归 时间复杂度O(m+n) 空间复杂度O(m+n)
# 因为要用到栈来存储中间结果,所以空间复杂度比较高
# 就是要找出来 f = f + b的格式
if list1 == None:
return list2
elif list2 == None:
return list1
elif list1.val < list2.val:
list1.next = self.mergeTwoLists(list1.next, list2)
# 一定要写return
return list1
else:
list2.next = self.mergeTwoLists(list1, list2.next)
return list2
# 方法4:迭代法
# 迭代是一种特殊的递归,迭代的空间复杂度为O(1)
# 其实就是方法1
推荐一个网站,可以用来看递归的过程细节
https://pythontutor.com
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:
if l1 is None:
return l2
elif l2 is None:
return l1
elif l1.val < l2.val:
l1.next = mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = mergeTwoLists(l1, l2.next)
return l2
# 示例
if __name__ == "__main__":
# 创建两个简单的链表
# l1=[2, 4, 6]
# l2=[1, 3, 5]
l1 = ListNode(2, ListNode(4, ListNode(6)))
l2 = ListNode(1, ListNode(3, ListNode(5)))
# 合并链表
merged = mergeTwoLists(l1, l2)
直接比较
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
# 方法1:
# 1. 首先检查两个链表是否为空,如果为空,则直接返回另一个链表。
# 2. 然后比较两个链表头节点的值,选择较小的那个作为合并后链表的头节点。
# 3. 使用一个循环来逐个比较两个链表的当前节点,将较小值的节点接到合并后的链表后面,并移动相应的指针。
# 4. 如果其中一个链表先遍历完成,将另一个链表的剩余部分直接连接到合并后的链表末尾。
if not list1:
return list2
if not list2:
return list1
# 找到两个链表中较小的头节点作为合并后链表的头节点
if list1.val < list2.val:
smaller_head = list1
larger_head = list2
else:
smaller_head = list2
larger_head = list1
current = smaller_head # 当前节点指针指向较小头节点
while list1 and list2:
if list1.val < list2.val:
# 把list1 插入到 current后面
next_node = list1.next # 保存list1的下一个节点
list1.next = current.next # 将list1节点接到current后面
current.next = list1 # 更新current的next指针
list1 = next_node # list1移动到下一个节点
else:
# 注意哈,如果第一次while循环的时候
# current=list2,则current会形成一个自环,
# 但是到下一次while循环的时候,这个环就解开了,就正常了
# 把list2给插到current后面
next_node = list2.next # 保存list2的下一个节点
list2.next = current.next # 将list2节点接到current后面
current.next = list2 # 更新current的next指针
list2 = next_node # list2移动到下一个节点
current = current.next # current移动到下一个节点
# 如果list1或list2未遍历完,将剩余部分直接连接到合并后的链表末尾
if list1:
current.next = list1
elif list2:
current.next = list2
return smaller_head
设一个dummy节点
要合并两个升序链表,我们可以创建一个新的链表,然后逐个比较两个链表当前节点的值,将较小值的节点添加到新链表中,并移动该节点的指针。重复这个过程,直到其中一个链表遍历完成,然后将另一个链表剩余的部分直接连接到新链表的末尾。
class Solution:
def mergeTwoLists(self, list1: ListNode, list2: ListNode) -> ListNode:
# 方法2:
# 搞一个新节点作为新链表,用来存放最后的答案
# 比较list1, list2,每次将最小的那个放到新链表后面
# 直到list1 or list2 为空,这样直接把剩下的不为空的给接到新链表后面
dummy = ListNode(-1) # 创建一个哑节点作为新链表的头节点
current = dummy # 当前节点指针指向哑节点
while list1 and list2: # 当两个链表都没有遍历完时
if list1.val < list2.val: # 比较两个链表当前节点的值
current.next = list1 # 将较小值的节点添加到新链表
list1 = list1.next # 移动较小值节点链表的指针
else:
current.next = list2
list2 = list2.next
current = current.next # 移动新链表的指针
# 如果list1或list2未遍历完,将剩余部分直接连接到新链表末尾
if list1:
current.next = list1
elif list2:
current.next = list2
return dummy.next # 返回新链表的头节点(跳过哑节点)