利用分治算法的Merge算法,算法的复杂度应该是merge算法的一半,虽然leetcode显示Accepted,但是时间复杂度应该没有满足。时间复杂度为:O((n+m)/2)
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int a=0,b=0,temp=0;
if((m+n)%2==1)
{
while((a+b)<=(m+n-1)/2)
{
if((A[a]<=B[b]&&a<m)||b>=n)
{
temp=A[a];
a++;
}
else
{
temp=B[b];
b++;
}
}
return temp;
}
else
{
int temp1=0, temp2=0;
while((a+b)<=(m+n)/2)
{
if((a<m&&A[a]<=B[b])||b>=n)
{
temp2=A[a];
if((a+b)==(m+n-2)/2)
temp1=temp2;
a++;
}
else
{
temp2=B[b];
if((a+b)==(m+n-2)/2)
temp1=temp2;
b++;
}
}
return (double)(temp1+temp2)/2;
}
}
};
以下算法是网上看到的,时间复杂度为O(nlog2(n))
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int *a=new int[m+n];
memcpy(a,A,sizeof(int)*m);
memcpy(a+m,B,sizeof(int)*n);
sort(a,a+n+m);
double median=(double) ((n+m)%2? a[(n+m)>>1]:(a[(n+m-1)>>1]+a[(n+m)>>1])/2.0);
delete a;
return median;
}
};
网上说的最好的算法,O(log(m+n))
算法将问题转化为寻找两个数组中第k小的数问题。
1、m+n为偶数时,median为第(m+n)/2和(m+n)/2+1小的数的和的1/2
2、m+n为奇数时,median为第(m+n)/2+1小的数
寻找两个数组中第k小数,由于两个数组都已经排好序,所以可以采取去除最小k/2的元素,查找剩余k/2的方法。这样每次都能减少k/2个查找对象。
pa = min(k / 2, m), pb = k - pa;这里确保数组a元素数量比较少,这样数组b必然能够有k/2个元素。否则k-pa有可能大于数组b的元素个数
double findKth(int a[], int m, int b[], int n, int k)
{
//always assume that m is equal or smaller than n
if (m > n)
return findKth(b, n, a, m, k);
if (m == 0)
return b[k - 1];
if (k == 1)
return min(a[0], b[0]);
//divide k into two parts
int pa = min(k / 2, m), pb = k - pa;
if (a[pa - 1] < b[pb - 1])
return findKth(a + pa, m - pa, b, n, k - pa);
else if (a[pa - 1] > b[pb - 1])
return findKth(a, m, b + pb, n - pb, k - pb);
else
return a[pa - 1];
}
class Solution
{
public:
double findMedianSortedArrays(int A[], int m, int B[], int n)
{
int total = m + n;
if (total & 0x1)
return findKth(A, m, B, n, total / 2 + 1);
else
return (findKth(A, m, B, n, total / 2)
+ findKth(A, m, B, n, total / 2 + 1)) / 2;
}
};