题目原型:
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)).
基本思路:
借助找第K个数的思想,大概意思就是在两个有序数组中,分别在第一个数组和第二个数组中找到第k个数,有三种情况:
A[k/2-1] = B[k/2-1]
A[k/2-1] > B[k/2-1]
A[k/2-1] < B[k/2-1]
第一种情况直接返回第k大的数,第二种请况是把B[0]到B[k/2-1]这k/2个数选中,表示这k/2个数在前k个最小的数之列。为什么呢?等会证明。然后从A[k/2]-A[M]和A[0]-A[N]中选取后k/2个数,以此类推。第三种情况类似。考虑的时候要注意数组长度的奇偶性。
好,现在我们证明下上面的情况,为什么说当A[k/2-1] > B[k/2-1]时我们要把B[0]到B[k/2-1]这k/2个数选中选中?想想,在B数组中有k/2-1个数比B[k/2-1]小,而A[k/2-1] > B[k/2-1],那么在A数组中至多有k/2-1个数比B[k/2-1]小,说明两个数组中最多有k/2+k/2-2个数比B[k/2-1]小,说明B[k/2-1]顶多排在第k/2+k/2-2+1<=k(不管是奇数还是偶数),所以所以B[0]到B[k/2-1]这k/2个数肯定比第K大的数小。
public double findMedianSortedArrays(int A[], int B[])
{
int m,n;
//边界条件的判断
if(A==null||A.length==0)
m = 0;
else
m = A.length;
if(B==null||B.length==0)
n = 0;
else
n = B.length;
//两个数组长度和为奇数
if(((m+n)&0x1)==1)
{
return findMedianSortedArrays(A, 0, 0, B, (m+n)/2+1,m,n);
}
//两个数组长度和为偶数,则要去中位数
else
return (findMedianSortedArrays(A, 0, 0, B, (m+n)/2,m,n)+findMedianSortedArrays(A, 0, 0, B, (m+n)/2+1,m,n))/2;
}
/**
*
* @param A 数组A
* @param startA 数组A的起始位置
* @param startB 数组B的起始位置
* @param B 数组B
* @param k 找第K个数时,还剩多少个数找。比如说我们要找中间数,第一次找出了k/2个数,那么接下来我们要找的数还剩k-k/2=k/2个
* @param m 数组A还剩下的长度
* @param n 数组B还剩下的长度
* @return
*/
public double findMedianSortedArrays(int A[], int startA,int startB,int B[],int k,int m , int n)
{
if(m>n)
return findMedianSortedArrays(B, startB, startA, A, k,n,m);
if(m==0)
return B[k-1];
if(k==1)
return Math.min(A[startA], B[startB]);
int indexA = startA+Math.min(k/2, m);
int indexB = startB+k - Math.min(k/2, m);
if(A[indexA-1]<B[indexB-1])
return findMedianSortedArrays(A,indexA,startB,B,k-Math.min(k/2, m),A.length-indexA,n);
else if(A[indexA-1]>B[indexB-1])
return findMedianSortedArrays(A,startA,indexB, B,Math.min(k/2, m),m,B.length-indexB);
else
return A[indexA-1];
}