算法分析:合并两个有序数组

前言

  • 这道题目说实话看起来很简单,就是把两个数组按顺序排序到一个新的数组里面,然后这两个数组还是有序的,但是这里面还有有学问的,一共三个方法,每个方法都是前面一个方法的进阶,所以还是很有讲究的。
  • 题目网址:https://leetcode-cn.com/problems/merge-sorted-array/
    在这里插入图片描述

第一种方法:暴力解法

  • 这种方法简单粗暴,就是把两个数组放到一起,然后直接进行排序。
  • 不多说直接上代码:
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        System.arraycopy(nums2,0,nums1,m,n);
        Arrays.sort(nums1);
    }
}

//普及一下这个方法
public static void arraycopy(Object src,
                             int srcPos,
                             Object dest,
                             int destPos,
                             int length)
意思是;将 src 数组里从索引为 srcPos 的元素开始, 复制到数组 dest 里的索引为 destPos 的位置, 复制的元素个数为 length 个. 

在这里插入图片描述

第二种解法:归并排序

  • 第一种解法直接简单粗暴,但是时间上还是相对于差一点,所以我们利用空间换时间的做法,通过遍历一遍就可以完成。

  • 而这种解法也就是归并排序的思想,意思是重新创建一个可以容纳下nums1 和 nums2 的数组,然后通过一起遍历判断完成合并

  • 第一步:创建一个 nums1 的数组大小的数组 nums1_copy
    在这里插入图片描述

  • 第二步,将两个指针指向nums1 和 nums2,然后进行遍历
    在这里插入图片描述

  • 第三步,将两个指针指向的数字进行判断,哪一方小就把哪一方放入第三个数组的指定索引中
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • 第四步,当一组数组循环遍历完之后,判断剩下的数组还有没有数字,如果有就复制到剩下的位置
    在这里插入图片描述
  • 这样就解决了,不说了看代码
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] nums = new int[m];
        System.arraycopy(nums1,0,nums,0,m);
        //指向nums1的指针
        int p = 0;
        //指向nums的指针
        int p1 = 0;
        //指向nums2的指针
        int p2 = 0;
        while(p1 < m && p2 < n){
            nums1[p++] = nums[p1] < nums2[p2] ? nums[p1++] : nums2 [p2++];
        }
        if(p1 < m){
            System.arraycopy(nums,p1,nums1,p1+p2,m+n-p1-p2);
        }
        if(p2 < n){
            System.arraycopy(nums2,p2,nums1,p1+p2,m+n-p1-p2);
        }
    }
}

在这里插入图片描述

第三种解法:优化归并排序

  • 上面一种方法一看性能提升了很高,但是空间换时间的做法确实有点亏,而这道题本身就给予我们更多的空间的数组,所以我们可以取巧,不需要再创建数组,直接将索引放在 nums1 的后面从后往前判断。
    在这里插入图片描述
  • 遍历就不再画图了,直接上代码把
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        //指向nums1的尾指针
        int p = nums1.length-1;
        //指向nums1的指针
        int p1 = m-1;
        //指向nums2的指针
        int p2 = n-1;
        while(p1 >= 0 && p2 >= 0){
            nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2 [p2--];
        }
        System.arraycopy(nums2,0,nums1,0,p2+1);
    }
}

在这里插入图片描述

总结

曾经我同学碰到这个问题,因为面试官直接让他用归并排序来完成,把他吓了一跳,因为归并排序本来就比较繁琐,所以他一紧张就没写出来,他来问我,我也懵逼,但是我今天才发现这题原来这么简单,我的天错失良机,所以还是要多学习。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值