原题如下:
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(m + n),O(log(m + n))的算法稍后研究下吧。
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int *temp = new int[m + n];
merge(A,m,B,n,temp);
if((m + n) % 2 == 0)
return (temp[(m + n) / 2] + temp[(m + n) / 2 - 1]) / 2.0;
else
return temp[(m + n) / 2];
}
void merge(int A[], int m, int B[], int n, int temp[]){
int i = 0, j = 0, k = 0;
while(i < m && j < n){
if(A[i] < B[j])
temp[k++] = A[i++];
else
temp[k++] = B[j++];
}
while(i < m)
temp[k++] = A[i++];
while(j < n)
temp[k++] = B[j++];
}
};
补(2014.06.12)
下面补充下O(log(m + n))的解法,显然在有序的情况下查找效率最高的是二分查找,此题也一样,当 m + n 为奇数时,寻找的即是第 (m + n)/2 + 1个数,而当m + n 为偶数时,寻找的是第(m + n)/2个数和第(m + n)/2 + 1个数的平均值,所以此题更一般的解法是寻找第k个数。按照二分查找的思路,分别在两个数组中查找第k/ 2个元素,当这两个元素相等时,即是寻找的第k个数,当A中第k/2个元素小于B中第k/2个元素时,则舍弃A中前k/2个元素,否则舍弃B中k/2个元素,然后依次递归。这里需要注意的特殊情况比较多,首先是当数组长度小于k/2时,需要选择其数组中最后一个元素,然后再据此确定较长数组中要查找的元素,所以在代码中总是假设A数组总是小于B数组的长度。其次是当一个数组长度为0时,直接返回第二个数组中第k个元素。还有就是当k等于1时返回两个数组中首元素较小的元素。可见,这种方法需要注意的细节特别多。。。
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int len = m + n;
if(len % 2 == 0)
return (findKthElem(A,m,B,n,len / 2) + findKthElem(A,m,B,n,len / 2 + 1)) / 2.0;
else
return findKthElem(A,m,B,n,len / 2 + 1);
}
double findKthElem(int *A,int m,int *B,int n,int k){ //m,n 为数组长度,k从1开始
if(m > n)
return findKthElem(B,n,A,m,k); //总是使m小于n
if(m == 0)
return B[k - 1];
if(k == 1)
return min(A[0],B[0]);
int pa = min(k / 2,m);
int pb = k - pa;
if(A[pa - 1] < B[pb - 1])
return findKthElem(A + pa,m - pa,B,n,k - pa);
else if(A[pa - 1] > B[pb - 1])
return findKthElem(A,m,B + pb,n - pb,k - pb);
else
return A[pa - 1];
}