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)).
题目解析:
(1)一般的想法,遍历数组A和数组B,时间复杂度为O((m+n)/2)。与题目不符合。
(2)进一步给出寻找答案,如下:
1、取出A数组的中值:A[Amid],在B数组中进行二分查找,寻找与A[Amid]接近的那个数。
Amid = 2;A[Amid] = 4;
在数组B进行查找,我们得到Bpos = 0;
2、我们查找的位置是pos = 6;又由于B[Bpos] < A[Amid],左边的长度为A[0:1] + B[0] = 3 < pos。因此我们要查找的中位数在右边,
可以递归的查找A[2:5],B[1:4],pos = pos - 3 = 3。
3、接下来Amid = 3,A[Amid] = 7,在B中查找,Bpos = 1,B[Bpos] = 5 < A[Amid] ,A[2:2]+B[1:1] =2 < pos,
递归求解A[3:5],B[2:4],pos = pos -2 = 1;
4、接下来Amid=4,A[Amid] = 10,在B中查找,Bpos = 3,B[Bpos] = 9 < A[Amid] ,A[3:3]+B[2:2]=2 >pos
递归求解A[3:3],B[2:2],pos = 1;
5、Amid = 3,A[Amid] = 7,在B中查找为Bpos = 2,B[Bpos] = 8 > A[Amid],A[3:3] = 1 == pos
递归求解A[3:3],pos = 1.
3、递归结束的条件是A数组或者B数组为空。
#include <iostream>
using namespace std;
int BiSearchPos(int array[],int begin,int end,int target)
{
int pre = begin;
int back = end;
while(begin <= end)
{
int mid = (begin + end)/2;
if(array[mid] == target)
return mid;
if(array[mid] > target)
end = mid - 1;
if(array[mid] < target)
begin = mid + 1;
}
if(<span style="color:#FF6666;"><strong>begin > end && end >= pre</strong></span>)
return end;
else
return begin;
}
int getNumberOfPos(int A[],int As,int Ae,int m,int B[],int Bs,int Be,int n,int pos)
{
if(m == 0)
{
return B[Bs + pos - 1];
}
if(n == 0)
{
return A[As + pos - 1];
}
int Amid = (As+Ae)/2;
int Bpos = BiSearchPos(B,Bs,Be,A[Amid]);
int ASubLen = Amid - As + 1;
int BSubLen = Bpos - Bs + 1;
if(A[Amid] <= B[Bpos])
{
if( ASubLen + BSubLen -1 >=pos )
return getNumberOfPos(A,As,Amid,ASubLen,B,Bs,Bpos-1,BSubLen-1,pos);
else
return getNumberOfPos(A,Amid+1,Ae,m-ASubLen,B,Bpos,Be,n-BSubLen+1,pos-(ASubLen+BSubLen)+1);
}else{
if( ASubLen + BSubLen -1 >=pos )
return getNumberOfPos(A,As,Amid-1,ASubLen-1,B,Bs,Bpos,BSubLen,pos);
else
return getNumberOfPos(A,Amid,Ae,m-ASubLen+1,B,Bpos+1,Be,n-BSubLen,pos-(ASubLen+BSubLen)+1);
}
}
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int pos = (m+n)/2;
if((m+n)%2 == 0)
{
double resPre = getNumberOfPos(A,0,m-1,m,B,0,n-1,n,pos);
double resBac = getNumberOfPos(A,0,m-1,m,B,0,n-1,n,pos+1);
return (resPre+resBac)/2;
}else{
double res = getNumberOfPos(A,0,m-1,m,B,0,n-1,n,pos+1);
return res;
}
}
int main(void)
{
int A[] = {3,4,5,6};
int B[] = {1,2,4};
int m = sizeof(A)/sizeof(int);
int n = sizeof(B)/sizeof(int);
m = 1;
n = 3;
double res = findMedianSortedArrays(A, m, B, n);
cout << res << endl;
system("pause");
return 0;
}