[LeetCode 88. 合并两个有序数组] | 刷题打卡

789 阅读1分钟
  • 掘金团队号上线,助你 Offer 临门! 点击 查看活动详情

本题核心

每天一道简单算法,防止老年痴呆~

题目描述

给你两个有序整数数组 nums1nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1nums2 的元素数量分别为 mn 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
 

提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[i] <= 109

解题思路

最简单方法,遍历nums1数组,然后往里插入nums2数组的值。

双指针: 根据题目提示nums1和nums2是两个已排序的数组,那么可以利用这个用双指针实现O(m+n)时间复杂度,O(m+n)空间复杂度的算法。

反向双指针:题目中还提示给出nums1后半部分的n长度都是空的,那么可以双指针倒序进行比较插值。实现 O(1)的空间复杂度。

解题代码

暴力简单解

public void merge(int[] nums1, int m, int[] nums2, int n) {
        for(int i=0;i<m+n;i++){
            if(i>=m){
               nums1[i]=nums2[i-m];
            }
        }
        Arrays.sort(nums1);
    }

双指针

 public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = 0, p2 = 0;
        int[] sorted = new int[m + n];
        int cur;
        while (p1 < m || p2 < n) {
            if (p1 == m) {//如果p1==m说明左边插完了。接着插nums2
                cur = nums2[p2];
                p2++;
            } else if (p2 == n) {如果p2==n说明右边插完了。接着插nums1
                cur = nums1[p1];
                p1++;
            } else if (nums1[p1] < nums2[p2]) {
                //先从nums1[0]和nums2[0]比较开始
                //如果左边小于右边,则p1自增
                cur = nums1[p1];//并把此时p1的值插入到sorted数组里
                p1++;
            } else {//反之则把p2的值插入到sorted数组里
                cur = nums2[p2];
                p2++;
            }
            sorted[p1 + p2 - 1] = cur;
        }
        for (int i = 0; i != m + n; ++i) {
            nums1[i] = sorted[i];
        }
    }

反向双指针

 public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1, p2 = n - 1;//左指针在nums1最后一位,右指针在nums2最后一位
        int tail = m + n - 1;//倒序开始下标为m+n-1
        int cur;
        while (p1 >= 0 || p2 >= 0) {//p1 p2小于0则已经遍历完了
            if (p1 == -1) {
                cur = nums2[p2];
                p2--;
            } else if (p2 == -1) {
                cur = nums1[p1];
                p1--;
            } else if (nums1[p1] > nums2[p2]) {//对比nums1和nums2最右边的数的大小
                cur = nums1[p1];//nums1比nums2的最右边更大则把最大值存在cur里
                p1--;//p1指针向左移
            } else {
                cur = nums2[p2];//反之p2向左移
                p2--;
            }
            nums1[tail] = cur;//赋值到nums1的右边value=0的位置
            tail--;
        }
    }    

##总结

简单算法,对于防止老年痴呆,非常好用👌