[Leetcode]-- Median of Two Sorted Arrays

参考:http://fisherlei.blogspot.com/2012/12/leetcode-median-of-two-sorted-arrays.html

 

[解题思路]
O(n)的解法比较直观,直接merge两个数组,然后求中间值。而对于O(log(m+n))显然是用二分搜索了, 相当于“Kth element in 2 sorted array”的变形。如果(m+n)为奇数,那么找到“(m+n)/2+1 th element in 2 sorted array”即可。如果(m+n)为偶数,需要找到(m+n)/2 th 及(m+n)/2+1 th,然后求平均。

而对于“Kth element in 2 sorted array”, 如下图,两个中位数 A[m/2] 和 B[n/2], 可以将数组划分为四个部分。而丢弃哪一个部分取决于两个条件:1, (m/2 + n/2)?k;2,A[m/2] ? B[n/2];

 

 

 

如果 (m/2 + n/2) > k,那么意味着,当前中位数取高了,正确的中位数要么在 Section 1或者Section3中。如果A[m/2] > B[n/2], 意味着中位数肯定不可能在Section 2里面,那么新的搜索可以丢弃这个区间段了。同理可以推断出余下三种情况,如下所示:

 

 

If (m/2+n/2+1) > k && am/2 bn/2 , drop Section 2
If (m/2+n/2+1) > k && am/2 bn/2 , drop Section 4
If (m/2+n/2+1) k && am/2 > bn/2 ,  drop Section 3
If (m/2+n/2+1) k && am/2 bn/2 ,  drop Section 1



简单的说,就是或者丢弃最大中位数的右区间,或者丢弃最小中位数的左区间。

 

public class Solution {
    public double findMedianSortedArrays(int A[], int B[]) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        int aLen = A.length;
        int bLen = B.length;
        if((aLen + bLen) % 2 ==0){
            return (getKthElement(A, 0, aLen - 1, B, 0, bLen - 1, (aLen + bLen) / 2) + getKthElement(A, 0, aLen - 1, B, 0, bLen - 1, (aLen + bLen) / 2 + 1)) / 2.0;
        } else {
            return getKthElement(A, 0, aLen - 1, B, 0, bLen - 1, (aLen + bLen) / 2 + 1);
        }
    }
    
    public int getKthElement(int A[], int aBeg, int aEnd, int B[], int bBeg, int bEnd, int k){
        if(aBeg > aEnd){
            return B[bBeg + (k - 1)];
        }
        if(bBeg > bEnd){
            return A[aBeg + (k - 1)];
        }
        
        int aMid = (aBeg + aEnd) >> 1;
        int bMid = (bBeg + bEnd) >> 1;
        int len = aMid - aBeg + bMid - bBeg + 2;
        
        if(len > k){
            if(A[aMid] < B[bMid]){
                return getKthElement(A, aBeg, aEnd, B, bBeg, bMid - 1, k);
            } else {
                return getKthElement(A, aBeg, aMid - 1, B, bBeg, bEnd, k);
            }
        } else {
            if(A[aMid] < B[bMid]){
                return getKthElement(A, aMid + 1, aEnd, B, bBeg, bEnd, k - (aMid - aBeg + 1));
            } else {
                return getKthElement(A, aBeg, aEnd, B, bMid + 1, bEnd, k - (bMid - bBeg + 1));
            }
        }
    }
}

 

posted @ 2014-01-25 17:40  Razer.Lu  阅读(469)  评论(0编辑  收藏  举报