不了解中位数算法的中位数来找到第k个元素

时间:2015-04-16 04:43:19

标签: java arrays algorithm median-of-medians

下面是我试图理解中位数算法中位数的代码(使用大小为5的块)。我理解如何获得输入的中位数,但我不确定如何编码块以保持递归输入,直到我只有中位数。在获得该中位数之后,我不确定如何将其用作枢轴来丢弃无用的信息来对输入进行分区。 getMediansArray返回一个大小为ceil(input.length / 5)的数组,而getMedians只返回一个数组的中位数(仅用于长度为< = 5的数组)。

public static int[] findKthElement(int[] input, int k) {
    int numOfMedians = (int) Math.ceil(input.length/5.0);
    int[] medians = new int[numOfMedians];
    medians = getMediansArray(input, medians)

    // (1) This only gets the first iteration of medians of the
    // input. How do I recurse on this until I just have one median?

    // (2) how should I partition about the pivot once I get it?
}

public static int[] getMediansArray(int[] input, int[] medians) {
    int numOfMedians = (int) Math.ceil(input.length/5.0);
    int[] five = new int[5];

    for (int i = 0; i < numOfMedians; i++) {
        if (i != numOfMedians - 1) {
            for (int j = 0; j < 5; j++) {
                five[j] = input[(i*5)+j];
            }
            medians[i] = getMedian(five);
        } else {
            int numOfRemainders = input.length % 5;
            int[] remainder = new int[numOfRemainders];
            for (int j = 0; j < numOfRemainders; j++) {
                remainder[j] = input[(i*5)+j];
            }
            medians[i] = getMedian(five);
        }
    }
    return medians;
}

public static int getMedian(int[] input) {
    Arrays.sort(input);
    if (input.length % 2 == 0) {
        return (input[input.length/2] + input[input.length/2 - 1]) / 2;
    }
    return input[input.length/2];
}

2 个答案:

答案 0 :(得分:1)

中位数的中位数基本上只是快速选择算法(http://en.wikipedia.org/wiki/Quickselect)的改进。虽然快速选择具有O(n)平均时间复杂度,但对于棘手的输入,它可以减慢到O(n ^ 2)。

在找到中位数中位数后你所做的只不过是快速选择算法的迭代。中位数的中位数具有很好的性质,它总是大于30%的元素和小于30%的元素。这保证了使用枢轴中位数的快速选择将在O(n)的最差时间复杂度下运行。请参阅:http://en.wikipedia.org/wiki/Median_of_medians

我建议你从实施快速选择开始。完成后,您可以使用已有的代码在快速选择的每个步骤中选择数据透视。

答案 1 :(得分:0)

如果我没记错的话(refreshing my memory)中位数中位数选择近似中位数。我不明白如何用它来选择第k个元素。