寻找两个正序数组的中位数

该篇博客探讨了一种寻找两个有序数组中位数的算法,利用折半查找策略降低复杂度。首先将问题转化为寻找第k小的元素,然后通过比较两个数组的第k/2个元素来逐步消减k值,处理数组越界情况,并在数组为空时给出解决方案。整个过程确保了在最坏情况下的时间复杂度为O(log(min(m, n))),其中m和n分别为两个数组的长度。
摘要由CSDN通过智能技术生成

折半查找

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int k = (nums1.length+nums2.length)/2;//代表第几个元素
        if((nums1.length+nums2.length)%2==1){
            return serch_k(nums1,nums2,k+1);
        }
            
        else{
            double mid = (serch_k(nums1,nums2,k)+serch_k(nums1,nums2,k+1))/2.0;
            return mid;
        }
            
    }

    public int serch_k(int[] nums1,int[] nums2,int k){
        int mid ;
        int left1=0,left2=0;
        int number1,number2;//确定比较第几个元素
        while(true){
            
            if(left1==nums1.length){
                return nums2[left2+k-1];
            }
            if(left2==nums2.length){
                return nums1[left1+k-1];
            }
            if(k==1){
                return Math.min(nums1[left1],nums2[left2]);
            }
            mid = k/2;
            number1=Math.min(left1+mid,nums1.length)-1;
            number2=Math.min(left2+mid,nums2.length)-1;
            if(nums1[number1]<=nums2[number2]){
                k=k-number1-1+left1;
                left1=number1+1;
            }else{
                k=k-number2-1+left2;
                left2=number2+1;
            }
        }
        

    }

    
}

2.算法思考(以下分析过程假定数组元素从1开始)

  1. 要寻找一个数组的中位数,就是将数组按从小到大排列,然后找到中间的数字(先只考虑有奇数个数字),也就是求第k =(n/2)+ 1个元素
  2. 所以求中位数的问题就转换为求第k小的元素的问题
  3. 考虑有序数组的性质 首先,数组可以随机存取,而数组是有序的,则可以直接找到第k小的元素,即a[k-1]
  4. 问题是寻找第k个元素(以下第k个元素,代表第k个小的元素),而寻找第k个元素,我们就不关心前k-1个元素

3.二分过程

  1. 现在是两个有序数组,去从中寻找第k个元素,我们要想办法把问题转换成寻找第1个元素或把一个数组给消去
  2. 我们怎么消去数组或减小k的值,在算法思考(4.)中提到,我们不关心前k-1个元素,那我们就是要消去俩个数组中的前k-1个元素
  3. 如何去消去k-1个元素,(举个例子,我们拿第一个数组中第一个元素,和第二个数组中第一个元素做对比,我们消去小的那个元素,然后将k减1),但是很明显一次消去一个元素效率太低,我们要尽可能多的消去元素,我们不妨将两个数组的第k/2个元素进行对比,将小的元素的前面元素包括自身全部消去,因为a[k/2]<b[k/2],比b[k/2]小的元素有k/2-1个,所以比a[k/2]小的元素最多有k-1个,即b[k/2]前面的所有元素都比a[k/2]前面的元素都大。
  4. 根据这种想法,我们就可以不停的消减k值,知道k为1,我们就可以直接通过比较两个数组第一个值的大小找到对应元素

特殊情况

  1. 不难想到当要去寻找a[k/2]和b[k/2]时可能造成数组越界问题,如果越界时,我们应该怎么办?
  2. 答:当数组越界时,我们应该选取数组的最后一个元素进行比较,但是会出现一个新的问题,这是我们所消去的元素个数就不是k/2了,我们需要根据排除树的个数减少k的值,而不能直接将k减去k/2
  3. 如果一个数组为空,则直接在另一个数组中寻找第k小的元素就可以
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值