Problem: There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays.
The overall run time complexity should be O(log (m+n)).
Key to solve: Bisection + Recursion
Convert find Median in 2 SortedArrays problem into
find Kth number k=(m+n)/2
There are 3 cases to locate Median during recursion process
1. if A[k/2]==B[k/2] => A[k/2] is Median
2. else if A[k/2]>B[k/2] => cut off elements before k/2 in B
3. else A[k/2]<B[k/2] => cut off elements before k/2 in A
We are able to cut off k/2 elements each time.
when k==1 return median
do not forget to check for special cases that including A.length==0 || B.length==0 || total==0
public class Solution {
public double findMedianSortedArrays(int A[], int B[]) {
int lenA=A.length;
int lenB=B.length;
int total=lenA+lenB;
if(total==0) return 0;
if(total%2==0){ //even length
return (helperBisection(A,B,0,lenA-1,0,lenB-1,total/2)+helperBisection(A,B,0,lenA-1,0,lenB-1,total/2+1))/2.0;
}else{ //odd length
return helperBisection(A,B,0,lenA-1,0,lenB-1,total/2+1);
}
}
private static int helperBisection(int[] A,int[] B, int aStart, int aEnd, int bStart, int bEnd, int k){
int lenA=aEnd-aStart+1;
int lenB=bEnd-bStart+1;
//always keep A[] length less than B[]
if(lenA>lenB) return helperBisection(B,A,bStart,bEnd,aStart,aEnd,k);
//check special case only for A is good enough here since we did swap in above
if(lenA==0) return B[k+bStart-1];
//base case
if(k==1){
return Math.min(A[aStart],B[bStart]);
}
int postA=Math.min(k/2,lenA);
int postB=k-postA;
if(A[aStart+postA-1]==B[bStart+postB-1]){
return A[aStart+postA-1];
}else if(A[aStart+postA-1]>B[bStart+postB-1]){
//cut off elements before k/2 in B
return helperBisection(A,B,aStart,aStart+postA-1,bStart+postB,bEnd,k-postB);
}else {
//cut off elements before k/2 in A
return helperBisection(A,B,aStart+postA,aEnd,bStart,bStart+postB-1,k-postA);
}
}
}