双指针
为了合并两个已排序的数组 nums1 和 nums2,并将结果存储在 nums1 中,我们可以采用双指针的方式从后向前进行合并。这种方法的好处是可以避免在nums1中移动元素,从而提高效率。
算法步骤
- 
初始化三个指针: - p1指向- nums1的有效部分的最后一个元素,即- m - 1。
- p2指向- nums2的最后一个元素,即- n - 1。
- p指向- nums1的最后一个位置,即- m + n - 1。
 
- 
从后向前遍历数组: - 比较 nums1[p1]和nums2[p2]:- 如果 nums1[p1] > nums2[p2],将nums1[p1]赋值给nums1[p],并将p1和p向前移动一位。
- 否则,将 nums2[p2]赋值给nums1[p],并将p2和p向前移动一位。
 
- 如果 
 
- 比较 
- 
如果 nums2中还有剩余元素(即p2>= 0),将这些元素复制到nums1的前面。
代码实现
            
            
              java
              
              
            
          
          class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // corner case
        // core
        int p1 = m - 1, p2 = n - 1, p = m + n - 1;
        while (p1 >= 0 && p2 >= 0) {
            if (nums1[p1] > nums2[p2]) {
                nums1[p--] = nums1[p1--];
            } else {
                nums1[p--] = nums2[p2--];
            }
        }
        while (p2 >= 0) {
            nums1[p--] = nums2[p2--];
        }
    }
}
            
            
              python
              
              
            
          
          def merge(nums1, m, nums2, n):
    # 设置指针
    p1, p2, p = m - 1, n - 1, m + n - 1
    
    # 从后向前合并
    while p1 >= 0 and p2 >= 0:
        if nums1[p1] > nums2[p2]:
            nums1[p] = nums1[p1]
            p1 -= 1
        else:
            nums1[p] = nums2[p2]
            p2 -= 1
        p -= 1
    
    # 如果 nums2 还有剩余元素,直接复制到 nums1
    # 如果 nums1 还有剩余元素,不需要处理,因为它们已经在正确的位置
    nums1[:p2 + 1] = nums2[:p2 + 1]
# 示例用法
nums1 = [1, 2, 3, 0, 0, 0]
m = 3
nums2 = [2, 5, 6]
n = 3
merge(nums1, m, nums2, n)
print(nums1)  # 输出: [1, 2, 2, 3, 5, 6]复杂度分析
- 时间复杂度 :O(m + n),因为我们最多需要遍历 nums1和nums2各一次。
- 空间复杂度 :O(1),因为我们是直接在 nums1上进行修改,没有使用额外的空间。