力扣:归并 寻找两个正序数组的中位数

489 阅读3分钟

归并

概念

何谓归并?归并其实是两个步骤,一个是归,还有一个是并。归是两个和两个以上的有序文件组成一起的过程,而并,就是将这些分组合并成一个新的有序文件。

例题分析

力扣之中,寻找两个正序数组的中位数,题目是这样的:给定两个大小分别为 mn 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数

这题的思路其实很简单,先进行排序,再寻找中位数即可,有很多种办法都能将他们进行排序,这里我采用归并的方法。

我们先来看看初步排序的过程,我假设数组nums1空间为5,数组nums2空间为6,然后开辟新的num辅助数组空间,来当做归并之后的数组。

基本思路

我们举例分析,将nums1 = {3, 5, 7, 8, 10}, nums2 = {4, 6, 8, 9, 11, 12}. 首先,将nums1的第一个值3nums2的第一个值5进行比较,那么较小值3,将会复制到num数组中,此时,nums1的下标索引自增指向5nums2下标索引不变化,num的下标在每一次赋值操作之后都需要索引加一。而后,继续按照这样的操作,另外虽然nums[3]nums[2]的值相同,但是统一先让nums1数组的下标索引自增。直到有一个数组全部遍历完,也就是当nums1的下标索引超过数组的长度时,让另外一个数组的值复制到nums中,最终完成归并。然后找出中位数。

图解

3_01.jpg

具体代码

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int l1 = nums1.length;
        int l2 = nums2.length;
        int[] num = new int[l1 + l2];
        // 第一个数组索引位置
        int i = 0;
        // 第二个数组索引位置
        int j = 0;
        // 定义的num数组索引位置
        int k = 0;

        //两个数组都有值时进行比较,之后向新定义的数组中赋值
        /*while(i < l1 && j < l2){
            if(nums1[i] < nums2[j]){
                num[k] = nums1[i++];
            }else{
                num[k] = nums2[j++];
            }
            k++;
        }*/
        for(i=0;i<l1&&j<l2;k++)
        {
            if(nums1[i] < nums2[j]){
                num[k] = nums1[i++];
            }else{
                num[k] = nums2[j++];
            }
        }
        // 第二个数组中元素已遍历完成,把第一个数组中剩余元素放到新建数组中
        if(i < l1){
            for (int a = i; a<l1; a++){
                num[k++] = nums1[a];
            }
        }else{
            for (int a = j; a<l2; a++){
                num[k++] = nums2[a];
            }
        }

        // 上面的代码其实就是合并两个有序数组,下面的代码就是找到中间位置,然后取出元素
        // 取余,因为如果余数为1,则直接取中间的那个元素,如果余数为0,需要取两个元素然后除以2
        int y = num.length % 2;
        // 中间元素位置的索引值
        int c = num.length / 2;
        if(y == 1){
            return num[c];
        }else{
            return (double)(num[c] + num[c - 1])/2;
        }
    }
}

代码分析

简单来说,代码分为两个阶段,一个是归并阶段,还有一个是寻找中位数的阶段。

归并阶段

归并阶段就是上述思想实现,期间采用for循环或者while循环都可以实现。

寻找中位数

寻找中位数,也需要判断单双。这个时候需要我们的求余数法则,取余,如果余数为1,则直接取中间的那个元素,如果余数为0,需要取两个元素然后除以2。

总结

每日力扣,感受代码,学习方法,总结经验。

希望对大家的学习有所帮助,谢谢!