Median of Two Sorted Arrays:
题意:给定两个被排序过的数组(从小到大),找出两个数组合并之后数组的中位数,时间复杂度在O(log(m+n))。通过函数返回值可以看出,当两数组长度和偶数时,返回中间两个数的平均数。
解法:首先观察要求的时间复杂度,一定不能采用将两个sorted array merge的方法。 O(log Min(m,n))方法:求出两个数组的中位数,midA,midB,若midA==midB,那么这个数就是所求。当midA>midB时,则中位数一定落在[midB,midA],那么midA右侧的所有数都不是中位数,midB左侧的所有数都不是中位数,于是将midA右侧和midB左侧分别截去相等的长度 temp(即midA右侧长度与midB左侧长度较小的数值),因为他们分别位于中位数两侧且等长,所以截去之后原来的问题转化为求长度为m-temp,n-temp的子问题。假设叫短的数组长度是m,较长的是n。那么每次问题就会将m的长度缩减一半,而n最终长度约等于n-m。当m小于某常数时,将较长数组中间m位保留,两侧截去,与较短数组merge。将组合后的数组排序,取出中位数即为所求。当n和m都小于某常数时,可以直接将两数组merge,排序求解。将m而分缩减的过程复杂度为logM,所剩常数排序所费时间为常数,所以算法总体复杂度为O(log Min(m,n))。
public class Solution150 {
public double findMedianSortedArrays(int A[], int B[]) {
return find(A,0,A.length-1,B,0,B.length-1);
}
privatedouble find(int[] a, int ax, int ay, int[] b, int bx, int by) {
intm=ay-ax+1;
intn=by-bx+1;
if(m==0&&n==0){
return0;
}
if(m==0){
returngetMid(b,bx,by);
}
if(n==0){
returngetMid(a,ax,ay);
}
if(m==1&&n==1){
return(a[ax]+b[bx]+0.0)/2;
}
if(m<=5&&n<=5){
int[]temp=new int[n+m];
for(int i=0;i<m;i++){
temp[i]=a[i+ax];
}
for(int j=0;j<n;j++){
temp[j+m]=b[j+bx];
}
qsort(temp,0,n+m-1);
returngetMid(temp,0,temp.length-1);
}
if(m>5&&n>5){
doublemidA=getMid(a,ax,ay);
doublemidB=getMid(b,bx,by);
if(midA==midB){
returnmidA;
}
if(midA>midB){
inttemp=Math.min(m/2-1, n/2-1);
returnfind(a,ax,ay-temp,b,bx+temp,by);
}else{
inttemp=Math.min(m/2-1, n/2-1);
returnfind(a,ax+temp,ay,b,bx,by-temp);
}
}
if(m<=5){
intrest=(n-5)/2;
inttempL=n-rest*2;
int[]temp=new int[m+tempL];
for(int i=0;i<m;i++){
temp[i]=a[ax+i];
}
for(int i=bx+rest;i<=by-rest;i++){
temp[i-bx-rest+m]=b[i];
}
qsort(temp,0,m+tempL-1);
returngetMid(temp,0,m+tempL-1);
}else{
intrest=(m-5)/2;
inttempL=m-rest*2;
int[]temp=new int[n+tempL];
for(int i=0;i<n;i++){
temp[i]=b[bx+i];
}
for(int i=ax+rest;i<=ay-rest;i++){
temp[i-ax-rest+n]=a[i];
}
qsort(temp,0,n+tempL-1);
returngetMid(temp,0,n+tempL-1);
}
}
privatedouble getMid(int[] a,int x,int y){
intn=y-x+1;
if(n==1){
returna[x];
}
if(n%2==1){
returna[x+n/2];
}else{
return(a[x+n/2-1]+a[x+n/2]+0.0)/2;
}
}
privatevoid qsort(int[] a, int x, int y) {
inti=x;
intj=y;
intt=a[(i+j)/2];
do{
while(a[i]<t){
i++;
}
while(a[j]>t){
j--;
}
if(i<=j){
inttemp=a[i];
a[i]=a[j];
a[j]=temp;
i++;
j--;
}
}while(i<=j);
if(i<y){
qsort(a,i,y);
}
if(j>x){
qsort(a,x,j);
}
}
}
O(log(m+n))方法:参考http://blog.csdn.net/yutianzuijin/article/details/11499917