12.(java实现)合并两个有序数组-排序法和双指针法


题目

问题描述1
合并两个有序数组
两个有序整数数组nums1和nums2,将nums2合并到nums1中,使nums1成为一个有序数组。

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

例如:
输入:
nums1 = [1, 2, 3, 5, 7, 9, 0, 0, 0, 0] ,m = 6;
nums2 = [2, 4, 6, 8] , n = 4;
输出:[1, 2, 2, 3, 4, 5, 6, 7, 8, 9]

一、思路

1.排序算法

时间复杂度 O( (n+m)log(n+m) )。

先合并两个数组,然后再使用排序算法。

2.双指针法使用空间复杂度优化时间复杂度***

时间复杂度O(n+m),空间复杂度O(n)。

  • 创建一个新的数组copy_nums1,用于存储num1的有效元素。
  • 定义p,p1,p2三个指针,分别指向nums1,copy_nums1,nums2;
  • 遍历copy_nums1,nums2两个数组,将元素有序的放进nums1中。

3.双指针法优化空间复杂度和时间复杂度***

时间复杂度O(n+m),空间复杂度O(1)。
从后往前遍历。

  • 创建三个指针:p表示nums1从后往前要插入的位置,p1表示nums1的有效元素的位置,p2表示nums2的有效元素的位置。
  • 遍历nums1,nums2两个数组的有效元素,将元素从后往前有序的放进nums1中。

二、代码

1.使用排序算法

代码如下:

     /**
     * 时间复杂度 O( (n+m)log(n+m) )
     *
     * @param nums1     数组1
     * @param m         数组1有效元素的个数
     * @param nums2:数组2
     * @param n:        数组2有效元素个数
     * @return 合并后的数组
     */
    public static int[] merge(int[] nums1, int m, int[] nums2, int n) {
        System.arraycopy(nums2, 0, nums1, m, n);  // nums1=[1,2,3,5,7,9,2,4,6,8]
        Arrays.sort(nums1);  // [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]
        return nums1;
    }

2.双指针法使用空间复杂度优化时间复杂度******

代码如下:

	
/**
     * 双指针法
     * 使用空间复杂度优化时间复杂度
     * 时间复杂度O(m+n),空间复杂度O(n)
     * @param nums1 数组1
     * @param m     数组1有效元素的个数
     * @param nums2 数组2
     * @param n     数组2有效元素个数
     * @return 合并后的数组
     */
    public static int[] merge1(int[] nums1, int m, int[] nums2, int n) {
        int[] copy_nums1 = new int[m];
        System.arraycopy(nums1, 0, copy_nums1, 0, m); // 将nums1拷贝到copy_nums1中
        int p1 = 0; // 指向copy_nums1
        int p2 = 0;  // 指向nums2
        int p = 0; // 指向nums1
        while (p1 < m && p2 < n) {
            nums1[p++] = copy_nums1[p1] > nums2[p2] ? nums2[p2++] : copy_nums1[p1++];
        }
        if (p1 < m) {
            // copy_nums1 没有复制完
            System.arraycopy(copy_nums1, p1, nums1, p1 + p2, m + n - p1 - p2);
        }
        if (p2 < n) {
            //nums2没有复制完
            System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
        }
        return nums1;
    }

3.双指针法优化空间复杂度和时间复杂度******

代码如下:

	
/**
     * 双指针法
     * 将空间复杂度优化为O(1)
     * 时间复杂度O(m+n)
     * 从后往前遍历
     * @param nums1 数组1
     * @param m     数组1有效元素的个数
     * @param nums2 数组2
     * @param n     数组2有效元素个数
     * @return 合并后的数组
     */
    public static int[] merge2(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1; // 指向copy_nums1
        int p2 = n - 1;  // 指向nums2
        int p = m + n - 1; // 指向nums1
        while (p1 >= 0 && p2 >= 0) {
            nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--];
        }
        //nums2没有复制完
        System.arraycopy(nums2, 0, nums1, 0, p2+1);
        return nums1;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值