合并两个有序数组

题目

  • 给定两个有序整数组nums1和nums2,将nums2合并到nums1中,是的num1成为一个有序数组。
说明
  • 初始化nums1和nums2的元素数量分别是m和n
  • 你可以假设nums1有足够的空间,空间大小大于或者等于m+n,以次来保存nums2中的元素
示例

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

输出: [1,2,2,3,5,6]

解析

  • 这里解析前我们明确下数组的拷贝:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
  • 参数介绍
    (1)Object src : 原数组
    (2)int srcPos : 从元数据的起始位置开始
    (3)Object dest : 目标数组
    (4)int destPos : 目标数组的开始起始位置
    (5)int length : 要copy的数组的长度
方法一:直接进行合并,合并完重新进行排序
  • 代码分析
    /**
     * 方法一: 直接合并,然后重新排序
     * @param nums1
     * @param m
     * @param nums2
     * @param n
     */
    public void merge1(int[] nums1, int m, int[] nums2, int n) {
        // 因为nums1的数组长度肯定是大于nums2的
        // 所以我们将nums1作为要输出的结果
        // 该函数的作用参考类上注解
        // 意思就是将nums2数组从0开始复制,复制到nums1中,起始位置从m(nums1数组的长度)开始,复制n条数组长度
        System.arraycopy(nums2, 0, nums1, m, n);
        Arrays.sort(nums1);
    }
方法二:双指针(从前往后)
  • 我们这里的双指针,利用的是从前向后的算法,还有一种算法是从后向前,这里我们不做详细介绍

  • 我们定义两个指针,p1和p2,p1为nums1的开头,p2为nums2的开头,p是保存在nums中的当前指针

  • 因为我们要直接往nums1中赋值,所以在赋值前,我们需要将nums1中的值直接拷贝出来

  • 具体的解释,可以看下面的代码的注释

  • 代码分析

    /**
     * 方法二:双指针法,从前向后执行
     * @param nums1 数组1
     * @param m 数组1的长度
     * @param nums2 数组2
     * @param n 数组2的长度
     */
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // 用来指向拷贝的nums1的头
        int p1 = 0;
        // 用来指向nums2的头
        int p2 = 0;
        // 用来保存当前保存在数组的下标
        int p = 0;
        // 复制一个数组nums1 我们用nums1做返回值,所以需要一个新的数组用来进行判断
        int[] nums_copy = new int[m];
        // 进行拷贝
        System.arraycopy(nums1, 0, nums_copy, 0, m);
        // 当nums1数组没有遍历完且nums2数组没有遍历完
        // 这时候遍历结束后 有可能会有一个数组有值没有进行赋值
        while (p1 < m && p2 < n) {
            // 判断nums1当前的值和nums2当前的值哪个小,哪个小就放到数组中,移动当前的下标
            nums1[p++] = nums_copy[p1] < nums2[p2] ? nums_copy[p1++] : nums2[p2++];
        }
        // 当p1小于m的时候,表示nums1数组还有剩余 p1+P2 可以写成p
        if (p1 < m) {
            System.arraycopy(nums_copy, p1, nums1, p1 + p2, m + n - (p1 + p2));
        }
        // 当p2小于n的时候,表示nums2数组还有剩余
        if (p2 < n) {
            System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - (p1 + p2));
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值