[LeetCode]Median of Two Sorted Arrays

来源:互联网 发布:python 中文注释 编辑:程序博客网 时间:2024/05/01 11:09

思路:

首先最容易的想到的是新开一个数组C[n+m],将数组A和B的值赋到C中,快排,找中数,时间复杂度为O((n+m)log(n+m))和空间复杂度为O(n+m)。这种方法完全没有利用到A、B是有序数组的条件,因此复杂度较高。


第二种方法是利用A、B是有序数组,用两个指示变量 i ,j 分别指向A和B的第一个元素,通过比较A[i]与B[j]:A[i]<B[j],i++;否则 j++,知道找到第(n+m)/2点。时间复杂度为O(n+m)。

以上两种方法均达不到题目对复杂度为O(log(n+m))的要求,还需要进一步优化。


我们先将问题转化为更一般的问题:寻找第k小的数。首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的k/2小的元素。这两个元素比较共有三种情况:>、<和=。

1、A[k/2-1] < B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。

2、A[k/2-1] < B[k/2-1],与情况1类似。

3、A[k/2-1] = B[k/2-1],则A[k/2-1]或B[k/2-1]即为第k小的数。

注:仔细想想,其实方法三是由方法二衍生而来的,第二种方法是每次抛弃一个元素(i++ or j++),而方法三是一次抛弃k/2个数据,提高了效率。

代码:

方法二:

class Solution {public:    double findMedianSortedArrays(int A[], int m, int B[], int n) {        int len=n+m;        int target=(n+m)/2;        int i=0,j=0;        int a[m+n+5],ans=0;        while(ans<=target)        {        if(j==n)        {        a[ans++]=A[i];        i++;        continue;        }        if(i==m)        {        a[ans++]=B[j];        j++;        continue;        }        if(A[i]>B[j])        {a[ans++]=B[j];        j++;                }        if(A[i]<=B[j])        {        a[ans++]=A[i];        i++;        }                }        double median;         if(len&1)        median=(double)a[target];        else        median=(double)(a[target]+a[target-1])/2;        return median;    }};
方法三 :

class Solution {public:    double findk(int A[], int m, int B[], int n, int k)    {        if(m>n)        return findk(B,n,A,m,k);        if(m==0)        return B[k-1];        if(k==1)        return min(A[0],B[0]);        int k1=min(m,k/2);        int k2=k-k1;        if(A[k1-1]<B[k2-1])        return findk(A+k1,m-k1,B,n,k-k1);        else if(A[k1-1]>B[k2-1])        return findk(A,m,B+k2,n-k2,k-k2);        return A[k1-1];    }    double findMedianSortedArrays(int A[], int m, int B[], int n) {        int k=m+n;        if(k&1)        return findk(A,m,B,n,k/2+1);        return (findk(A,m,B,n,k/2)+findk(A,m,B,n,k/2+1))/2;    }};



0 0