描述
两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。
样例
给出数组A = [1,2,3,4,5,6] B = [2,3,4,5],中位数3.5
给出数组A = [1,2,3] B = [4,5],中位数 3
实现:
public class Solution {
/*
* @param A: An integer array
* @param B: An integer array
* @return: a double whose format is *.5 or *.0
*/
public double findMedianSortedArrays(int[] A, int[] B) {
if((A==null && B==null) || (A.length==0 && B.length==0)) return 0;
if(A.length==0){
if(B.length%2==0){
return (double)(B[B.length/2]+B[B.length/2-1])/2;
}
else{
return B[B.length/2];
}
}
if(B.length==0){
if(A.length%2==0){
return (double)(A[A.length/2]+A[A.length/2-1])/2;
}
else{
return A[A.length/2];
}
}
int index;
if((A.length+B.length)%2==0) index=(A.length+B.length)/2-1;
else index=(A.length+B.length)/2;
if(B[B.length-1]<=A[0]){
int[] temp=A;
A=B;
B=temp;
}
if(A[A.length-1]<=B[0]){
if(index<A.length){
if((A.length+B.length)%2==0){
if(index<A.length-1) return (double)(A[index]+A[index+1])/2;
else return (double)(A[index]+B[0])/2;
}
else return A[index];
}
if(index>=A.length){
index-=A.length;
if((A.length+B.length)%2==0){
return (double) (B[index]+B[index+1])/2;
}
else return (double) B[index];
}
}
int ia=0, ja=A.length-1;
int ib=0, jb=B.length-1;
int ma = -1, mb = -1;
while(ia<=ja || ib<=jb){//核心是折半查找
ma=(ia+ja)/2;
mb=(ib+jb)/2;
if(ma+mb+1==index) {
if(ma==A.length-1 || mb==B.length-1) break;
if(A[ma]<=B[mb] && ma<ja && A[ma+1]>=B[mb]) break;
if(A[ma]>=B[mb] && mb<jb && A[ma]<=B[mb+1]) break;
}
if(ma+mb+1>index){
if(ia<=ja && A[ma]>B[mb]) ja=ma-1;
else jb=mb-1;
}
else{
if(ia<=ja && A[ma]<B[mb]) ia=ma+1;
else ib=mb+1;
}
}
if((A.length+B.length)%2==0){
if(ma<A.length && mb<B.length){
return (double)(Math.max(A[ma], B[mb])+Math.min(A[ma+1], B[mb+1]))/2;
}
}
return (double)Math.max(A[ma], B[mb]);
}
}