1. 题目
查找两个有序数组的中值,时间复杂度为O(log (m+n))
2. 分析
1:类似 Merge Sorted Array,先把两个有序数组合并
当合并到第len/2个元素的时候返回那个数即可
不需要保存结果数组
算法时间复杂度是O(m+n),空间复杂度是O(1)
2:借助算法导论10.3节中的order statistics思想
问题等价于求两数组中第k=len/2大的数
基本思路是每次通过查看两数组的第k/2大的数(假设是A[k/2],B[k/2])
如果A[k/2]=B[k/2],说明A[k/2]和B[k/2]即为两个数组剩余元素的第k大的数
如果A[k/2]>B[k/2], 那么说明B的前k/2中不存在我们要的第k大的数
反之则去除A的前k/2,这样每次排除k/2个元素,最终k=1时即为结果
总的时间复杂度是O(logk),空间复杂度也是O(logk),即递归栈的大小
因为k=(m+n)/2,所以复杂度是O(log(m+n))
注意传参时候为find(A, B, i + posA, i2, j, j + posB - 1, k - posA);
不要写成find(A, B, i + posA, i2, j, j + posB - 1, k);
3. 代码
class Solution {
public:
double findMedianSortedArrays(vector<int>& A, vector<int>& B) {
int lenA = A.size();
int lenB = B.size();
int len = lenA + lenB;
if(len & 0x1)
return find(A, B, 0, lenA - 1, 0, lenB - 1, len / 2 + 1);
else
return (find(A, B, 0, lenA - 1, 0, lenB - 1, len / 2) +
find(A, B, 0, lenA - 1, 0, lenB - 1, len / 2 + 1)) / 2.0;
}
private:
int find (vector<int>& A, vector<int>& B, int i, int i2, int j, int j2, int k)
{
int m = i2 - i + 1;
int n = j2 - j + 1;
if(m > n)
return find(B, A, j, j2, i, i2, k);
if(m == 0)
return B[j + k - 1];
if(k == 1)
return min(A[i], B[j]);
int posA = min(k / 2, m);
int posB = k - posA;
if(A[i + posA - 1] == B[j + posB - 1])
return A[i + posA -1];
else if(A[i + posA - 1] < B[j + posB - 1])
return find(A, B, i + posA, i2, j, j + posB - 1, k - posA);
else
return find(A, B, i, i + posA - 1, j + posB, j2, k - posB);
}
};