参考: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)); } } } }