两个不同大小的排序数组的中位数

时间:2017-10-16 21:04:20

标签: java algorithm sorting quicksort median

我正在尝试找到两个不同大小的排序数组的中位数。但有一些情况它不起作用,我无法弄清楚原因。我在下面列出了我的实现。

我确实在网上有类似的解决方案。但我刚刚开始学习算法,所以我想尽可能多地做自己。非常感谢您的帮助!

public double median(Point[] arr, int start, int end) {
    int n = end - start + 1;
    if (n % 2 == 0) {
        return (double) (arr[start + (n/2)].getSz() + arr[start + (n/2) - 1].getSz())/2;
    }
    else {
        return (double) arr[start + (n/2)].getSz();
    }
}

public double getMedian(int aStart, int aEnd, int bStart, int bEnd) {
    int m = aEnd - aStart + 1;
    int n = bEnd - bStart + 1;
    double median = 0;

    if (m == 0 && n > 0) {
        return median(arr2, 0, bEnd);
    }

    if (m > 0 && n == 0) {
        return median(arr1, 0, aEnd);
    }

    if (m == 1 && n == 1) {
        return (double) (arr1[0].getSz() + arr2[0].getSz())/2;
    }

    if (m == 2 && n == 2) {
        median = (double) (Math.max(arr1[aStart].getSz(), arr2[bStart].getSz()) + Math.min(arr1[aEnd].getSz(), arr2[bEnd].getSz()))/2;
        return median;
    }

    double m1 = median(arr1, aStart, aEnd);
    double m2 = median(arr2, bStart, bEnd);

    if (m1 == m2) {
        return m1;
    }

    if (m1 < m2) {
        if (m % 2 == 0) {
            aStart = aStart + (m/2) - 1;
            index = 1;
        }
        else {
            index = 2;
            aStart = aStart + m/2;
        }
        bEnd = bStart + n/2;
    }
    else {
        if (n % 2 == 0) {
            index = 3;
            bStart = bStart + n/2 - 1;
        }
        else {
            index = 4;
            bStart = bStart + n/2;
        }
        aEnd = aStart + m/2;
    }
    return (getMedian(aStart, aEnd, bStart, bEnd));
}

以下是逻辑中断的示例:
arr1 = 6,20,28,29,36,41
arr2 = 14,15,33,47,53,66,79,98

正确中位数= 34.5
估计中位数= 31

2 个答案:

答案 0 :(得分:1)

看起来算法中存在一些问题。

首先在几个地方使用0代替aStart和bStart:

   if (m == 0 && n > 0) {
        return median(arr2, ->0<-, bEnd);
    }

    if (m > 0 && n == 0) {
        return median(arr1, ->0<-, aEnd);
    }

    if (m == 1 && n == 1) {
        return (double) (arr1[->0<-].getSz() + arr2[->0<-].getSz())/2;
    }

其次;在最后一个区块中,你必须小心地抛出高于中位数的数量。

if (m1 < m2) {
    if (m % 2 == 0) {
        aStart = aStart + (->m<-/2) - 1;
        index = 1;
    }
    else {
        index = 2;
        aStart = aStart + ->m<-/2;
    }
    bEnd = bStart + ->n<- /2;
}

并且您也不得丢弃最接近中位数的中位数的数据。希望有所帮助。

答案 1 :(得分:0)

要获得两个排序数组 A B 的中位数,您需要弄清楚如何将两个数组拆分为低部分和高部分,以便所有低部分元素都是&lt; =所有高部分元素,低部分和高部分中元素的总数是相同的(在1之内)。

低元素将包含来自 A 的一些 x 元素,以及(A.length + B.length)/ 2 - x 来自 B 的元素。

要查找 x ,您可以对 x 的可能值进行二进制搜索。设 MID =(A.length + B.length)/ 2 。然后,假设 x ,如果 A [x-1]> B [MID-x] ,则 x 太大。否则它不会太大。这个条件足以让你在每次迭代中将值的范围减少一半。

一旦你知道阵列的分割位置,你知道 max(A [x-1],B [MID-x-1])是低部分中的最高元素,并且 min(A [x],B [MID-x])是高部分中的最低元素,这就是计算中位数所需的全部内容。