问题概述
给你两个按非递减顺序排列的整数数组 nums1 和 nums2。将 nums2 合并到 nums1 中,使合并后的数组同样按非递减顺序排列。nums1 的长度为 m + n,其中前 m 个元素是有效的,后 n 个元素设置为 0 且应被忽略。
解法 1:从末尾双指针(推荐)
工作原理
从两个数组的末尾开始合并,以避免覆盖 nums1 中尚未处理的元素:
python
class Solution:
def merge(self, nums1, m, nums2, n):
i = m - 1 # nums1 中最后一个有效元素
j = n - 1 # nums2 中最后一个元素
k = m + n - 1 # nums1 中最后一个位置
# 从末尾开始合并
while i >= 0 and j >= 0:
if nums1[i] > nums2[j]:
nums1[k] = nums1[i]
i -= 1
else:
nums1[k] = nums2[j]
j -= 1
k -= 1
# 复制 nums2 中剩余元素(如果有)
while j >= 0:
nums1[k] = nums2[j]
j -= 1
k -= 1
复杂度分析
- 时间复杂度: O(m + n) - 单次遍历两个数组
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 推荐 - 最优解
- 从末尾合并避免覆盖未处理的元素
- 处理所有边界情况,包括一个数组为空的情况
关键洞察
从末尾合并至关重要,因为:
- 如果从开头合并,我们会覆盖
nums1中尚未处理的元素 - 通过从末尾开始,我们首先使用
nums1末尾的额外空间 - 这确保我们在合并过程中不会丢失任何数据
对比
| 方法 | 时间 | 空间 | 最佳适用 |
|---|---|---|---|
| 双指针(末尾) | O(m + n) | O(1) | 大多数情况,最优解 |
总结
从末尾开始的双指针技术是原地合并有序数组的最优解决方案。这种方法高效地使用 nums1 中的额外空间,而不需要额外的内存。