leetcode4——Median of Two Sorted Arrays

题目大意:给出两个升序数组,以O(log(m+n))求出数组中所有数的中位数

分析:如果不要求时间复杂度,可以用归并求解,归并排序的时间复杂度是O(m+n)。

要以O(log(m+n))的时间复杂度求解需要使用二分搜索。

找中位数=>找切分点,将所有数分成长度相同的两半。

                 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]

原问题=>找切分点i、j满足:

1、i + j = m - i + n - j(或:m - i + n - j + 1) 如果 n ≥ m,只需要使 i = 0 ~ m, j = (m + n + 1) /2 - i

2、B[j-1] ≤ A[i] 以及 A[i−1] ≤ B[j](因为要满足max(left_part)≤min(right_part))

 

二分搜索切分点i(起始imin=0,imax=m)可能遇到的三种情况:

1、(j = 0 or i=m or B[j−1]≤A[i]) 或是(i = 0 or j = n or A[i−1]≤B[j]) 这意味着 i 是完美的,我们可以停止搜索。

2、i < imax and B[j−1]>A[i] 这意味着 i 太小,我们必须增大它。

3、i > imin and A[i−1]>B[j] 这意味着 i 太大,我们必须减小它。

当找到目标i时,中位数为:

max(A[i−1],B[j−1]), 当 m + n 为奇数时;[max(A[i−1],B[j−1])+min(A[i],B[j])]/2 , 当 m + n 为偶数时

代码:转载自https://leetcode.com/articles/median-of-two-sorted-arrays/#

class Solution {
    public double findMedianSortedArrays(int[] A, int[] B) {
        int m = A.length;
        int n = B.length;
        if (m > n) { // to ensure m<=n
            int[] temp = A; A = B; B = temp;
            int tmp = m; m = n; n = tmp;
        }
        int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
        while (iMin <= iMax) {
            int i = (iMin + iMax) / 2;
            int j = halfLen - i;
            if (i < iMax && B[j-1] > A[i]){
                iMin = i + 1; // i is too small
            }
            else if (i > iMin && A[i-1] > B[j]) {
                iMax = i - 1; // i is too big
            }
            else { // i is perfect
                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、付费专栏及课程。

余额充值