题目描述
思路
两个数组合并,最后的结果是要扩容。通常有两个方向考虑,一个是借助第三方数组(容器),另一个是在数组自身扩容。根据题目意思,优先选择自身扩容
暴力解法:把nums2的有效部分覆盖掉nums1的无效部分,然后对nums1进行原地排序。
双指针:根据当前指针位置的和与目标值的大小关系来调整指针位置,最终找到符合条件的数字。从尾部开始合并,这样可以避免数组元素的重复移动或使用额外空间,从而优化空间复杂度。
解题方法
- 设置指针变量:index1,index2分别指向nums1、nums2的尾部,循环比较nums1与nums2的元素大小,大的放在nums1后面
- 更新指针
- 需要考虑但一方数组元素全部比较完后,另一方数组如何处理数据。因为在nums1中排列,故nums1剩余时,对结果无影响。nums2有剩余时,剩余的元素均小于nums1最小的元素,只需要把剩余的元素切片到nums1中。
图解:
复杂度
时间复杂度:O(M+N)
空间复杂度:O(1)
Code
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
# 三指针
index1, index2 = m - 1, n - 1
index = n + m - 1
# 比较两个数组的元素,谁大就放到index的位置。注意:这是从后往前排列
while index1 >= 0 and index2 >= 0:
if nums1[index1] <= nums2[index2]:
nums1[index] = nums2[index2]
index2 -= 1
else:
nums1[index] = nums1[index1]
index1 -= 1
index -= 1
# 如果nums2元素有剩余时,说明剩余的元素是比nums小的
if index2 >= 0:
# 切片
nums1[: index2 + 1] = nums2[: index2 + 1]