高频算法:Leetcode88 合并两个有序数组

今天来讲Leetcode第88题,首先贴一下题目
高频算法:Leetcode88 合并两个有序数组_第1张图片
通过题目可以知道我们有两个递增的数组nums1和nums2,并且nums1是可以同时容纳这两个数组的所有元素的,如果我们想用更低的空间复杂度来解决这道题的话,肯定是将num2中的元素加入到nums1中

此时最简单的解法其实就已经出来了,我们需要将nums1中的元素和nums2中的元素进行比较,如果nums1的元素更小,我们就取下一个元素接着进行比较;如果nums2中的元素更小的话,我们则需要将这个元素插入nums1中的这个位置,并且将nums1中的所有元素都后移一位

这个方法最差的情况下nums1和nums2都需要被遍历一遍,所以时间复杂度是O(m * n),空间复杂度因为我们没有引入新的数据结构所以是 O(1)

上面的解法很容易想到,但是方法的时间复杂度有点高,如果我们想优化一下,该怎么做呢?

我们是不是可以通过空间换时间的方式再来解决一遍这个问题,既然上面的方法麻烦的地方就在于如果nums2中的元素比nums1中的元素小的话,nums1其后的元素都要后移一位,我们就单独创建一个数组来装我们的结果,是不是就不用这么复杂了呢?

我们只需要每次将nums1和nums2的元素取出来比较一下,将较小的元素放入到我们新的返回数组中,直到nums1或nums2中的元素都放入到新数组中,那么余下的那个数组中的元素都是比较大的,我们直接将剩余元素放到我们的返回数组即可,画一张图来理解一下这个过程
高频算法:Leetcode88 合并两个有序数组_第2张图片
代码示例

public static void merge(int[] nums1, int m, int[] nums2, int n) {
    // 创建返回数组
    int[] result = new int[m + n];
    int index = 0;
    int i = 0, j = 0;
    // 比较两个数组的元素大小并放入返回数组中
    while (i < m && j < n) {
        if (nums1[i] > nums2[j]) {
            result[index++] = nums2[j++];
        } else {
            result[index++] = nums1[i++];
        }
    }
    // 只剩下一个数组的场景时,将剩余元素放入返回数组中
    while (j < n) {
        result[index++] = nums2[j++];
    }
    while (i < m) {
        result[index++] = nums1[i++];
    }
    // 最后别忘了将返回数组赋值给我们的nums1
    for (int k = 0; k < result.length; k++) {
        nums1[k] = result[k];
    }
}

这个方法使用了额外的数组来解决这个问题,在空间复杂度方面变为了O(m + n),但是在时间复杂度上降为了O(m + n),那么有没有一种方法,既能不增加空间复杂度,又能吧时间复杂度控制在*O(m + n)*呢?

其实也是有方法的,题目中已经告诉我们了nums1中后n个元素都是0,如果我们倒过来想这个问题,先把两个数组中更大的元素放入到nums1中,就可以完美解决这个问题,直接上图
高频算法:Leetcode88 合并两个有序数组_第3张图片
代码示例

public void merge(int[] nums1, int m, int[] nums2, int n) {
    int tail = m + n;
    // 比较两个数组中的数字,将较大的数字放入到nums1的尾部
    while (m > 0 && n > 0) {
        if (nums1[m - 1] > nums2[n - 1]) {
            nums1[--tail] = nums1[--m];
        } else {
            nums1[--tail] = nums2[--n];
        }
    }

	// 如果nums1先被放完,则nums2需要将剩余元素接着放到nums1中
	// 如果nums2先被放完的话则不需要处理了,就像演示图中一样
    while (n > 0) {
        nums1[--tail] = nums2[--n];
    }
}

你可能感兴趣的:(算法,数据结构,leetcode)