提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
错误思路
如果从左往右地把 n u m s 2 合并到 n u m s 1 中,假设 n u m s 2 [ 0 ] < n u m s 1 [ 0 ] ,那么 n u m s 2 [ 0 ] 会直接覆盖掉 n u m s 1 [ 0 ] ,这不是我们期望看到的。
正确思路
如果从右往左地把 n u m s 2 合并到 n u m s 1 中,是否会发生错误的覆盖呢 ? 我们来看几个例子: − n u m s 1 = [ 1 , 2 , 3 , ∗ , ∗ , ∗ ] , n u m s 2 = [ 4 , 5 , 6 ] 。这里我用 ∗ 表示可以填入的空位。在这个例子中, n u m s 2 可以直接填入 n u m s 1 后面的 3 个空位,得到 [ 1 , 2 , 3 , 4 , 5 , 6 ] ,没有任何错误覆盖。 − n u m s 1 = [ 1 , 2 , 6 , ∗ , ∗ , ∗ ] , n u m s 2 = [ 3 , 4 , 5 ] 。这里 n u m s 1 中的 6 是最大的,应当填入末尾。现在 n u m s 1 = [ 1 , 2 , ∗ , ∗ , ∗ , 6 ] ,注意 n u m s 1 [ 2 ] 这个位置现在空出了。然后把 n u m s 2 中的数字填入空位,得到 [ 1 , 2 , 3 , 4 , 5 , 6 ] ,没有任何错误覆盖。 − 上面的例子表明,把 n u m s 1 中的数字移到另一个空位,又产生了一个新的空位,所以剩余空位的个数是不变的,我们总是有空位可以让 n u m s 2 的数字填入,不会发生错误覆盖,这是如下算法正确的前提。
代码如下(示例):
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
p1, p2, p = m - 1, n - 1, m + n - 1
while p2 >= 0: # nums2 还有要合并的元素
# 如果 p1 < 0,那么走 else 分支,把 nums2 合并到 nums1 中
if p1 >= 0 and nums1[p1] > nums2[p2]:
nums1[p] = nums1[p1] # 填入 nums1[p1]
p1 -= 1
else:
nums1[p] = nums2[p2] # 填入 nums2[p1]
p2 -= 1
p -= 1 # 下一个要填入的位置
作者:灵茶山艾府
链接:https://leetcode.cn/problems/merge-sorted-array/solutions/2385610/dao-xu-shuang-zhi-zhen-wei-shi-yao-dao-x-xxkp/
来源:力扣(LeetCode)