给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
这道题是对两个数组进行融合(merge)并排序,其实就应该想到归并排序。但是 merge sort 合并的时候我们通常是新建一个数组,先比较两个数组的头元素,然后将较小的推到最终的数组中。但是这道题目要求的是原地修改,其实我们只要从后往前比较,并从后往前填入第一个数组即可,因为第一数组的后面部分是预留的空白,从后往前填入是不影响前面的值的。
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
while m > 0 and n > 0:
if nums1[m - 1] < nums2[n - 1]:
nums1[n + m - 1] = nums2[n - 1]
n -= 1
else:
nums1[n + m - 1] = nums1[m - 1]
m -= 1
# 第一步比较结束后有两种情况:
# 1. 指针 m>0,n=0,此时不需要做任何处理
# 2. 指针 n>0,m=0,此时需要将nums2指针左侧元素全部拷贝到nums1的前n位
if n > 0:
nums1[:n] = nums2[:n]
参考资料
归并排序
def merge_sort(lists):
if len(lists) <= 1:
return lists
# 把这个序列分成左右两个部分,每个部分都递归调用函数本身,
# 分别返回一个有序数组,最后将两个有序数组再合并成一个有许数组
middle = len(lists)//2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
def merge(left, right):
# left和right分别为两个有序数组
combined_list = []
i = j = 0
# 用两个指针,分别遍历数组的每个元素
while j < len(left) and i < len(right):
# 哪个指针对应的元素小,就将这个值写入待合并数组,相应指针右移
if left[j] < right[i]:
combined_list.append(left[j])
j += 1
else:
combined_list.append(right[i])
i += 1
# 如果左指针先到尽头
if j == len(left):
# 就把右指针当前位置及其往右所有元素追加进待合并数组
for i in right[i:]:
combined_list.append(i)
# 同样的也适用于右指针先到尽头的情况
else:
for i in left[j:]:
combined_list.append(i)
return combined_list