88. 合并两个有序数组

73 阅读1分钟

打卡面试经典150题,第一题

1.题目概述

本题主要考察编程者的工程编程模拟过程。题目不难,但还是有一点难度,需要考虑一些边界条件。

2.分析过程

合并2个有序数组,可以通过3个指针来模拟。指针i,j分别指向num1,num2数据所在的位置,指针k指向nums1中合并后的位置,然后向前移动2个指针i,j,直到其中一个指针小于0。 然后分成2种情况。

    1. i < 0(等同于 j >= 0)

此时num1有效数据已经全部重新填充,num2 还没有完全填充到num1中,因此需要把num2的数据全部填充到num1中。

  • 2. j < 0

此时num2 已经完全填充到num1中,num1已经是完全排好序的数组不需要再排序。

3.边界条件

考虑nums1 和nums2长度为0 的情况。

  • n = 0:nums2为空,nums1不用再处理,直接返回。
  • m = 0,nums1为空,需要把nums2数据全部填充到nums1
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // 处理边界条件
        if(n == 0){
            return;
        }
        int j = n - 1;
        if(m == 0){
             for(;j >= 0; j--){
                nums1[j] = nums2[j];
            }
            return;
        }
        int i = m - 1;
        //填充位置索引
        int k = m + n -1;
        while(i >= 0 && j >= 0){
            if(nums1[i] >= nums2[j]){
                nums1[k] = nums1[i];
                i--;
            }else{
                nums1[k] = nums2[j];
                j--;
            }
            k--;
        }

        // j==0 表示数组nums2还剩一个元素nums2[0]没有复制过去
        if(j >= 0) {
            for(;j >= 0; j--){
                nums1[j] = nums2[j];
            }
        }
    }
}