其他分享
首页 > 其他分享> > 力扣4 寻找两个正序数的中位数

力扣4 寻找两个正序数的中位数

作者:互联网

力扣4 寻找两个正序数的中位数

二分杀我!

image-20220101140355841

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        //官方解答的核心就是两条线使两个数组分成四段,比较贴近两条线的那四个数(有可能是三个)
        //官方解答没问题,但属实是吓唬人,其实说白了就是二分一下较小的数组。
        //因为短的数组位置确定了,大的位置必定唯一
        //为使得程序好写,当出现了小的越界了的情况,依然存在第四个数,设那个数为最小值或最大值。
//保证num1为最小的数组
        if(nums1.length>nums2.length){
            int[] temp = nums1;
            nums1 = nums2;
            nums2 = temp;
        }
//求出总的左边个数(奇数偶数统一处理)
        int n1 = nums1.length;
        int n2 = nums2.length; 
        int total_left = (n1+n2+1)/2;

//算法本身:二分短的数组,该二分的终止条件为本题核心
//短数组的线恰好画对了的条件是:
// num1[mid-1]<=num2[long_mid]&&num1[mid]>=nums2[long_mid-1];(即 交叉也保序)
// 官方解答比较牛掰 判断一个条件即可,因为在二分的过程中,分到最后第二个条件必然满足了。
        int left = 0;
        int right = n1;
//这里的left和right 说明一下,前几天做二分心态崩了,导致我不做题了。
//这道题就解了当时的惑
// 我当时的理解是 left 可取0所以是表示下标;right是长度,所以表示是个数,这两个怎么能在一起出现呢?
//现在看来我真是煞笔,这里的定义不同,这里是线的取值范围,1到5 五个数,一共六个空。

        while(left<right){
            //若令mid为短数组的中间线位置右边的数的下标(mid恰好代表线左边的数有几个)
            int mid = (left+right+1)/2;
            //则长数组线左边必然有total_left-mid个,
            int long_mid = total_left-mid;

            if(nums1[mid-1]>nums2[long_mid]){//这里出现了[mid-1]需要担心数组越界,需要担心mid取0,但是mid取不到0。
            //ps:如果数组长度就为1 是能取到0的 但可惜while条件都不满足,跳不进来。。。。程序压根走不到这。
            
                //说明num1的线画的太靠右了
                right = mid-1;
            }else{
                left = mid; //但凡是left=mid或者right=mid了都得考虑死循环。
            }
        }
           //结局的left是我心心念念的线右边的数的下标。下面稍作处理返回即可。
        //把那四个数找出来,对越界的情况稍作处理。使其依然能参与比较。
        
        int line1_left = (left==0?(int)-1e7:nums1[left-1]);
        int line1_right = (left==n1)?(int)1e7:nums1[left];
        int line2_left = (total_left-left==0)?(int)-1e7:nums2[total_left-left-1];
        int line2_right = (total_left-left==n2)?(int)1e7:nums2[total_left-left];

        
        if((n1+n2)%2==1){
                return (double)Math.max(line1_left,line2_left);
        }
                return (Math.max(line1_left,line2_left)+Math.min(line1_right,line2_right))/2f;
    }
}

标签:right,int,mid,中位数,力扣,序数,nums1,nums2,left
来源: https://www.cnblogs.com/Rogy/p/15755363.html