【题目】
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)).
【题意】
有两个有序的数组,找出这两数组整合后的中位数,要求时间复杂度O(nlogn)
【思路】
要找这两个排序数组的中位数,数组长度分别是Len(A)=m和Len(B)=n
如果m+n是奇数,则中位数是两个排序数组组合之后的第(m+n+1)/2个数
如果m+n是偶数,则中位数是两个排序数组组合之后的第(m+n)/2和第(m+n)/2+1个数的平均值
则原题的目标可以转化为两个数组整合之后的第K小数问题
解决方案1,
由于A和B都是排好序的数组,借用归并的思想,把两个数组进行合并,然后取kth,复杂度是O(n+m)。 不符合题设要求。
解决方案2
O(log(m+n)) 表明必须使用二分法来解决。
以一次迭代为例,保证m<n的顺序,要找两个集合第k小数,我们分别看A[pa-1]和B[pb-1], 其中pa = k/2, pb = k-k/2。如果A[pa-1]<B[pb-1],则A[pa-1]及其之前的所有元素都应该包含在前k小集合里,第k小的点肯定在 A[pa~m-1]或B[0~pb]中;所以下一步迭代就变成了求数组A[pa~m-1]和B[0~pb]中的第k-pa小值问题。
【代码】
class Solution {
public:
double getKth(int A[], int B[], int m, int n, int k){
if(m>n)
return getKth(B, A, n, m, k);
if(m==0)
return B[k-1];
if(k==1)
return min(A[0], B[0]);
int pa = min(m, k/2), pb = k - pa;
if(A[pa-1] < B[pb-1]){
return getKth(A+pa, B, m-pa, pb, k-pa);
}
else if(A[pa-1] > B[pb-1]){
return getKth(A, B+pb, pa, n-pb, k-pb);
}
else
return A[pa-1];
}
double findMedianSortedArrays(int A[], int m, int B[], int n) {
double median = 0;
if((m+n)%2==1){
median = getKth(A, B, m, n, (m+n+1)/2);
}
else{
median = (getKth(A, B, m, n, (m+n)/2) + getKth(A, B, m, n, (m+n)/2+1))/2;
}
return median;
}
};