40.寻找两个正序数组的中位数(二分排除法)

在这里插入图片描述

== case1==:此时k/2都比数组的有效长度小
在这里插入图片描述

case2:数组长度小于k/2

在这里插入图片描述
case3:查找的只剩下一个数组
在这里插入图片描述
注意:偶数长度的情况,可能出现0.5的小数位数,注意使用乘的0.5自动转换为double类型
在这里插入图片描述

具体代码:

class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int n = nums1.length;
    int m = nums2.length;
    //注意这个left和right对应的不是数组的有效序号,而是从1开始计数的具体位置
    int left = (n + m + 1) / 2;
    int right = (n + m + 2) / 2;
    
    //将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k(即left==right) 
    //注意这里乘的0.5这样可以转换为double(不要单纯的除以2,还是int)
    return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1,    right))*0.5;  

}


   //每次更新出数组nums1和nums2有效索引,对应的剩余的查找数组个数k(采用二分法)
   /**
   start:即为有效查找的数组的开始序号
   end:即为数组的尾部序号
   k:即为剩余离中位数的距离的个数
   note:注意数组小标与第几个数的区别,数组的序号需要相对于低基数减1
    */
    private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
        //求出对应的有效查找数组的长度
        int len1 = end1 - start1 + 1;
        int len2 = end2 - start2 + 1;


        //让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1 (避免了分类讨论时的重复操作)
        if (len1 > len2){
            //相当于利用对称的性质
             return getKth(nums2, start2, end2, nums1, start1, end1, k);
        }

        if (len1 == 0){
            //总是nums1先跳出循环(单独取出数组nums2的数)
             return nums2[start2 + k - 1];//(个数转换为序号减1)
        }

        if (k == 1){
            //此时需要判断最后一个数
             return Math.min(nums1[start1], nums2[start2]);
        }

        //用于更新有效查找的数组的长度(2选1)
        //找到两个数的带比较的两个数的有效索引的位置
        int i = start1 + Math.min(len1, k / 2) - 1;
        int j = start2 + Math.min(len2, k / 2) - 1;

        if (nums1[i] > nums2[j]) {//更新小的数组nums2索引以及剩余离中位数的距离的个数
            return getKth(nums1, start1, end1, nums2, j + 1, end2, k - Math.min(len2, k / 2));
        }
        else {//更新小的数组nums1索引以及剩余离中位数的距离的个数
            return getKth(nums1, i + 1, end1, nums2, start2, end2, k - Math.min(len1, k / 2));
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值