初阶。
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.merge两个数组,找出第K大。时间复杂度O(m+n)
2.用两个指针分别*pa和*pb分别指向两个数组A,B的第一个元素。比较,如果数组A小的话,那么pa++,并且m++;如果数组B小的话,那么pb++,并且m++.最终当m等于k的时候,得到了答案。时间复杂度是o(k),当k接近于m+n的时候,复杂度也是o(m+n).
3.二分查找。比较A[k/2]和B[k/2],如果A[k/2]<=B[k/2],那么A的k/2肯定小于AUB的第K大,也就是说A的前k/2一定在前k-1中,于是将A数组的前k/2扔掉,反之扔掉B的前k/2。将k减小到k/2.重复直到k=1.比较A和B中的第一个数。时间复杂度为O(logn)
函数终止的条件无非几种:
1.如果A或者B为空,直接返回B[k-1]或者A[K-1]
2.当k=1时,返回min(A[0].B[0]);
3.当A[k/2-1]==B[k/2-1]时,返回A[k/2-1]或者B[k/2-1]
另外注意,如果A或者B的长度不足k/2的情况。
class Solution{
public:
double findMedianSortedArrays(int A[],int m,int B[],int n){
int total = m + n;
if (total & 0x1)
return find_kth(A,m,B,n,total/2+1);
else
return (find_kth(A,m,B,n,total/2) + find_kth(A,m,B,n,total/2 + 1))/2.0;
}
private:
static int find_kth(int A[],int m,int B[],int n,int k){
//assume m is no bigger than n
if (m > n) return find_kth(B,n,A,m,k);
if (m == 0) return B[k-1];
if(k == 1) return min(A[0],B[0]);
int ia = 0;
if (k/2 > m)
ia = m;
else
ia = k/2;
int ib = 0;
if (k/2 > n)
ib = n;
else
ib = k/2;
if(A[ia - 1] < B[ib - 1])
return find_kth(A+ia,m-ia,B,n,k-ia);
else if(A[ia -1] > B[ib -1])
return find_kth(A,m,B+ib,n-ib,k-ib);
else
return A[ia -1];
}
};
进阶。
有N台机器,每台机器上有一个有序大数组,需要求得所有机器上所有数中的第K大。注意,需要考虑N台机器的并行计算能力。
思路。
二分答案S。将S广播到所有机器上,用二分法算出有多少比这个数小,汇总结果后在调整S的大小。