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

class Solution {
    public double findMedianSortedArrays(int[] A, int[] B) {
        int m = A.length;
        int n = B.length;
        if (m > n) { 
            return findMedianSortedArrays(B,A); // 保证 m <= n
        }
        int iMin = 0, iMax = m;
        while (iMin <= iMax) {
            int i = (iMin + iMax) / 2;
            int j = (m + n + 1) / 2 - i;
            if (j != 0 && i != m && B[j-1] > A[i]){ // i 需要增大
                iMin = i + 1; 
            }
            else if (i != 0 && j != n && A[i-1] > B[j]) { // i 需要减小
                iMax = i - 1; 
            }
            else { // 达到要求,并且将边界条件列出来单独考虑
                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;
    }
}

  1. int m = A.length; int n = B.length;:获取两个数组的长度。

  2. if (m > n) { return findMedianSortedArrays(B,A); }:为了保证 m <= n,如果 m > n,我们就调用自己并将两个数组交换位置。

  3. int iMin = 0, iMax = m;:初始化 i 的搜索范围。

  4. while (iMin <= iMax) { ... }:开始二分查找。

  5. int i = (iMin + iMax) / 2;:计算当前的 i。

  6. int j = (m + n + 1) / 2 - i;:计算对应的 j。

  7. if (j != 0 && i != m && B[j-1] > A[i]) { iMin = i + 1; }:如果 B[j-1] > A[i],说明 i 太小了,我们需要增大 i。

  8. else if (i != 0 && j != n && A[i-1] > B[j]) { iMax = i - 1; }:如果 A[i-1] > B[j],说明 i 太大了,我们需要减小 i。

  9. else { ... }:如果找到了合适的 i,我们就计算中位数。

    • int maxLeft = ...;:计算左边的最大值。
    • if ( (m + n) % 2 == 1 ) { return maxLeft; }:如果总数是奇数,直接返回 maxLeft。
    • int minRight = ...;:计算右边的最小值。
    • return (maxLeft + minRight) / 2.0;:如果总数是偶数,返回左边最大值和右边最小值的平均值。
  10. return 0.0;:默认返回值,实际上这段代码永远不会执行到这一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值