Hard
思路
- merge array最直接, 但是时间复杂度为O(m + n) ,超时
- 为满足log级别的时间复杂度,采用binary search
- 二分法找到
过程
- 确定较短数组, 作为a(对较短数组做二分查找时间更短)
- corner case, A长度为0, 直接返回B的中位数
- 中位数(不论奇偶),公式:
((double)B[(lenB - 1) / 2] + (double)B[lenB / 2]) / 2
- 求A的左半边元素(Aend + AStart)/2 ,B的左半边元素(B的为(len + 1)/2 - cutA, +1 的原因为当总长度为奇数时直接return最右边元素
- 得到L1, L2, R1, R2
- 更新分割线,判断(L1 > R2) : end = cutA -1 (L2 > R1) : start = cutA + 1
- 如果都满足,说明分割线找对, 可以返回
- 偶数: L1,L2 的MAX + R1,R2的MAX /2
代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] A = nums1;
int[] B = nums2;
if(A.length > B.length)
return findMedianSortedArrays(B, A);
int lenA = A.length, lenB = B.length, len = lenA + lenB;
if(A.length == 0)
return ((double)B[(lenB - 1)/2] + (double)B[(lenB)/2]) / 2;
int start = 0, end = lenA;
int cutA, cutB;
while(start <= end){
cutA = (start + end) /2 ;
cutB = (len + 1) / 2 - cutA;
double L1 = (cutA == 0)?Integer.MIN_VALUE:A[cutA - 1];
double R1 = (cutA == lenA)?Integer.MAX_VALUE:A[cutA];
double L2 = (cutB == 0)?Integer.MIN_VALUE:B[cutB - 1];
double R2 = (cutB == lenB)?Integer.MAX_VALUE:B[cutB];
if(L1 > R2){
end = cutA - 1;
}else if(L2 > R1){
start = cutA + 1;
}else {
if(len % 2 == 0){
return (Math.max(L1,L2) + Math.min(R1,R2)) / 2;
}else
return Math.max(L1,L2);}
}
return -1;
}
}