描述:给定两个有相同数序的数组,求其中中间值。
思路一;使用二路归并思想,另外申请一个数组空间存储归并后的序列。时间复杂度线性,空间复杂度线性;
#include<stdlib.h>
class Solution{
public:
int median(int A[],int m,int B[],int n)
{
if(m==0&&n==0)return -1;
if(m==0)return B[(n-1)/2];
if(n==0)return A[(m-1)/2];
int *C=(int *)malloc(sizeof(int)*(m+n));
int i,j,k;
for(i=0,j=i,k=i;i<m&&j<n;k++)
{
if(A[i]<=B[j])
{
C[k]=A[i++];
}
else
{
C[k]=B[j++];
}
}
while(i<m)C[k++]=A[i++];
while(j<n)C[k++]=B[j++];
return C[(m+n-1)/2];
}
};
思路二:不需要另外申请空间,归并时只做到中间位置不需要做后面的排序工作。时间复杂度线性,空间复杂度为1;
class Solution{
public:
int median(int A[],int m,int B[],int n)
{
if(m==0&&n==0)return -1;
if(m==0)return B[(n-1)/2];
if(n==0)return A[(m-1)/2];
int mid=(m+n-1)/2;//标记中间值位置,若是偶数则取左边;
int k=0; //判断是否达到中间位置;
int i,j;
for(i=0,j=i;i<m&&j<n;k++)
{
if(A[i]<=B[j])
{
if(k==mid)return A[i];
i++;
}
else
{
if(k==mid)return B[j];
j++;
}
}
while(i<m)
{
if(k==mid)return A[i];
i++;
k++;
}
while(j<n)
{
if(k==mid)return B[j];
j++;
k++;
}
}
};
思路三:由于两个数组都是有序的,可以直接判断A[mid/2-1]与B[mid/2-1],当A[mid/2-1]<B[mid/2-1]时,则A[0]~A[mid/2-1]必定在A∪B中间值左边,反之则B[0]~B[mid/2-1]在A∪B中间值左边,若A[mid/2-1]=B[mid/2-1]时,A[mid/2-1]与B[mid/2-1]即为A∪B的中间值。时间复杂度为对数级,空间复杂度为1;
class Solution{
public:
int median(int A[],int m,int B[],int n)
{
int mid=(m+n-1)/2;
return find_kth(A[],m,B[],n,mid+1);
}
private:
static int find_kth(int A[],int m,int B[],int n,int k)
{
if(m>n)return find_kth(int B[],int n,int A[],int m,int k);
if(m==1) return B[k-1];
if(k==1) return A[0]<B[0]?A[0]:B[0];
//确定边界
int i=k/2<m?k/2:m;
int j=k-i;
if(A[i-1]<B[j-1])
{
return find_kth(A+i,m-i,B,n,k-i);
}
else if(A[i-1]>B[j-1])
{
return find_kth(A,m,B+j,n-j,k-j);
}
else{
return A[i-1];
}
}
};