20191222——第四题 寻找两个有序数组的中位数

本文深入探讨了如何在两个已排序的数组中找到中位数的高效算法,通过详细的步骤和代码示例,展示了如何使用二分查找法来确定中位数,适用于不同长度的数组组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中位数
我们首先了解一下什么叫中位数,中位数在统计学中被用来:

将一个集合划分为两个长度相等的子集,其中一个子集中的元素总是大于另一个子集中的元素

在一个长度为n的数组A中,如果我们可以在任意一个位置将数组划分,有n+i中划分方式。n=0时,right_part 为空,同理,n=n+i的时候,left_part 为空。
采用同样的方法,有一个数组B,将B划分为两个部分。
将 \text{left_A}left_A 和 \text{left_B}left_B 放入一个集合,并将 \text{right_A}right_A 和 \text{right_B}right_B 放入另一个集合。 再把这两个新的集合分别命名为 \text{left_part}left_part 和 \text{right_part}right_part:

      left_part          |        right_part
A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

重要的事:如果我们能确认
在这里插入图片描述
那么我们可以说,已经将A,B所有的元素划分成为相同长度的两个部分,且其中一部分的元素总是大于另一部分的元素。
那么我们所求的中位数
在这里插入图片描述

我们想要保证这两个条件,需要保证:
在这里插入图片描述
第一个条件不用说了,从一半开始,如果A,B元素数量和是偶数,那么left_part与right_part相等,中位数等于left_part[i+j/2 -1] 与right_part[i+j/2 -1]的和除以2,如果是奇数那么更好办了中间的数就是中位数。

条件分析
在这里插入图片描述
在这里插入图片描述

所以我们接下来要做的是:
寻找对象i
在这里插入图片描述
接着,我们可以按照以下步骤来进行二叉树搜索:

class Solution {
    public double findMedianSortedArrays(int[] A, int[] B){
        // 获取A与B的数组元素个数
        int m = A.length;
        int n = B.length;
        // 如果m的个数大于n的个数,那么需要调换一下两个数组
        if(m > n){
            int [] temp =A ;
            A = B ;
            B = temp;
            int tempint   = m;
            m = n;
            n =tempint ;
        }
        //设置二分查找的左右max与min
        int min = 0;
        int max = m;
        int halfLen = (m+n+1)/2;
        //进行循环逻辑
        while(min <= max){
            // i是中间位置的元素,j是根据i有关
            int i = (min+max)/2;
            int j = halfLen -i;
            if(i < max && B[j-1] > A[i]){
                min = i+1;
            }else if(i > min && A[i-1] > B[j]){
                max = i-1;
            }else{
                //这个时候的i是正确的i
                int maxleft = 0;
                if(i == 0){
                    maxleft = B[j-1];
                }
                else if(j == 0){
                    maxleft = A[i-1];
                }else{
                    maxleft = Math.max(A[i-1],B[j-1]);
                }
                if((m + n) %2 == 1){
                    return maxleft;
                }
                int minRight = 0;
                if (i == m) { minRight = B[j]; }
                else if (j == n) { minRight = A[i]; }
                else { minRight = Math.min(B[j], A[i]); }

                return (maxleft + minRight) / 2.0;


            }
        }
        return 0.0;
    }
}

**暴力解法**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值