阵列复杂度

时间:2015-08-03 11:12:44

标签: java arrays algorithm data-structures heap

我使用最大堆来查找数组中的k个最大元素,如下所示:

1)我已经构建了给定数组的前k个元素(arr [0]到arr [k-1])的Min Heap MH。 O(k)的

2)对于每个元素,在第k个元素(arr [k]到arr [n-1])之后,将它与MH的根进行比较。

...... a)如果元素大于根,则将其设为root并为MH

调用heapify

...... b)否则忽略它。

//步骤2是O((n-k))

3)最后,MH有k个最大元素,MH的根是第k个最大元素。

我已经搜索了网络,第二步的复杂性向我显示了O(nk)logk,我认为应该是(nk)* O(k)如果我们使用自下而上的方法构建堆。因为每一步我只是在找到更大的元素时替换root。并且堆积k个元素的数组的复杂性是O(k)

我错了请澄清。我只是需要知道我的想法是否正确?

我的方法如下:

private static void createMinHeap(int[] arr) {

        for (int i = arr.length / 2; i >= 0; i--) {
            restoreDown(arr, i);
        }

    }

    private static void restoreDown(int[] arr, int i) {

        int left = (2 * i) + 1;
        int right = (2 * i) + 2;
        int num = arr[i];

        while (right <= arr.length) {

            if (num <= arr[right] && num <= arr[left]) {
                arr[i] = num;
                return;
            } else if (arr[right] < arr[left]) {
                arr[i] = arr[right];
                i = right;
            } else {
                arr[i] = arr[left];
                i = left;
            }

            left = (2 * i) + 1;
            right = (2 * i) + 2;
        }

        if (left == arr.length - 1 && arr[left] < num) {
            arr[i] = arr[left];
            i = left;
        }

        arr[i] = num;

    }

2 个答案:

答案 0 :(得分:2)

您的推理几乎是正确的,但是对于大小为k的堆,heapify操作需要O(log k)。因此,总复杂度为O(n log k)。为什么?在最坏的情况下,您应该为每个n-k个剩余元素执行heapify。由于k已修复且n可以是任意大,因此O(n)步,最终会给O(n log k)

另见:

答案 1 :(得分:-2)

Selection algorithm允许您在O(n)时间内找到第k个元素或数组中的k个最大元素。