【问题标题】:Time complexity of finding median of two sorted arrays查找两个排序数组的中位数的时间复杂度
【发布时间】:2014-10-12 02:33:22
【问题描述】:

我遵循中值比较算法来查找两个排序数组的中值并在 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);
    }
}

谢谢。

【问题讨论】:

  • 为子数组创建一个抽象,而不是从一个复制到另一个。
  • 你能解释一下吗?谢谢
  • 它将是 (max(1,3) + min(2,4))/2 = (3+2)/2 这与数组是 [1,2,3, 4]

标签: arrays algorithm time-complexity median


【解决方案1】:

getMedian可以多加两个参数:ab的起始索引,就不需要复制数据了。

另外,不是sn-p:

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);
    }
}

【讨论】:

  • 感谢您的建议,让我测试一下。是的,提到了定义,好像长度是偶数,那么它是两个中间元素的平均值,如果它是奇数,那么它是中间元素。
  • 集合的中位数通常定义为集合大小为奇数时的中间元素或偶数时中间元素的平均值。以前从未听说过“选择任何元素”!来源:mathworld.wolfram.com/StatisticalMedian.html
  • 有趣的@polvoazul!已经快 7 年了,我不知道我是如何得出这个定义的 :) 我将删除注释,因为似乎另一个定义确实被普遍接受。
  • 没问题!这些事情有时会发生?
猜你喜欢
  • 2020-10-27
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2017-12-18
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
相关资源
最近更新 更多