找到两个排序数组的中位数的时间复杂度

时间:2014-08-19 04:50:42

标签: arrays algorithm time-complexity median

我遵循中位数比较算法来查找两个已排序数组的中位数并在java中实现。根据算法时间复杂度是O(lgn),但由于它涉及创建子数组(方法createSubArr),我认为根据我的代码,它是O(n)。以下是我实施的代码。

class Median
{
    public static void main (String[] args)
    {
        int[] a = {1,12,15,26,38,40};
        int[] b = {2,13,17,30,45,50};
        System.out.println(getMedian(a,b,6));
    }

    private static int median(int[] a, int n){
        if(n % 2 == 0) return (a[n/2] + a[(n/2)-1])/2;
        else return a[n/2];
    }
    private static void show(int[] a) {
        for(int i=0;i<a.length;i++) System.out.print(a[i] + " ");
        System.out.println();
    }
    private static int[] createSubArr(int[] a, int start){
        int[] sub = new int[a.length-start];
        for(int i=0;i<a.length-start;i++) sub[i] = a[start+i];
        return sub;
    }
    private static int getMedian(int[] a, int[] b,int n){
        int m1,m2;
        int start=-1;
        int ans = -1;
        if(n<=0) return -1;
        if(n==1) return (a[0] + b[0])/2;
        if(n==2) return (Math.max(a[0],b[0])  + Math.min(a[1],b[1]) )/2;
        m1=median(a,n);
        m2=median(b,n);
        if(m1 < m2) {
            if(n%2==0){
                start = (n/2)-1;
                a = createSubArr(a,start);
            }
            else {
                start = (n/2);
                a = createSubArr(a,(n/2));
            }
        }else{
            if(n%2==0){
                start = (n/2)-1;
                b = createSubArr(b,start);
            }
            else {
                start = (n/2);
                b = createSubArr(b,start);
            }
        }
        return getMedian(a,b,n-start);
    }
}

感谢。

1 个答案:

答案 0 :(得分:0)

您可以向getMedian添加两个额外参数:ab的起始索引,然后无需复制数据。

此外,而不是代码段:

if (n%2 == 0) {
    x = n/2 - 1;
} else {
    x = n/2;
}

您只需使用(n-1)/2;

即可

您需要调整以下两种方法来获得O(lg n)算法(未经测试):

private static int median(int[] a, int a0, int n){
    if(n % 2 == 0) return (a[a0 + n/2] + a[a0 + (n/2)-1])/2;
    else return a[a0 + n/2];
}

private static int getMedian(int[] a, int a0, int[] b, int b0,int n){
    int m1,m2;
    int start=-1;
    int ans = -1;
    if(n<=0) return -1;
    if(n==1) return (a[a0] + b[b0])/2;
    if(n==2) return (Math.max(a[a0],b[b0])  + Math.min(a[a0+1],b[b0+1]) )/2;
    m1=median(a, a0,n);
    m2=median(b, b0,n);
    if(m1 < m2) {
        return getMedian(a, (n-1)/2, b, b0, n - (n-1)/2);
    } else {
        return getMedian(a, a0, b, (n-1)/2, n - (n-1)/2);
    }
}

Offtopic:你自己想出了一个偶数长度阵列的中位数的定义,还是给出了?我认为选择两个“中间元素”中的一个更为常见,无论你最喜欢哪一个。我希望中位数是你输入数组中的一个元素,你的方法无法保证。