以下合并算法的时间复杂度是多少?

时间:2017-10-02 18:59:11

标签: algorithm merge parallel-processing time-complexity

您将获得int[][] lists(排序的int数组数组)。 你要合并所有这些。 什么是时间复杂度?

我尝试通过将数组分成对并将所有对并行合并来做到这一点。

public static List<Integer> merge(int[][] array) throws InterruptedException {
        // number of array remaining to be merged
        int remaining = array.length;

        while (remaining > 2) {
            List<Thread> threads = new LinkedList<>();
            for (int i = 0; i < remaining - 1; i += 2) {
                // DoMerge is a runnable that merges 
                // two array in O(n1 + n2) time (n1 and n2 are
                // lengths of the two given arrays)
                // DoMerge will also put the merged array
                // at position i in the given array
                Thread mergeThread = new Thread(new DoMerge(i, i + 1, array));
                threads.add(mergeThread);
                mergeThread.start();
            }
            //  wait for them all to finish
            for (Thread t : threads) {
                t.join();
            }
            // move the newly merged list to the front
            for (int j = 1, i = 2; i < remaining; i += 2, ++j) {
                array[j] = array[i];
                array[i] = null;
            }
            remaining = (int) Math.ceil(remaining / 2.0);
        }

        return combine(lists[0], lists[1]);
    }

(假设处理器数量> = = arrays.length)

认为这个时间复杂度是log(n).k其中k是要合并的每个数组的最大长度,n是数组的数量。

这是对的吗?

1 个答案:

答案 0 :(得分:2)

不幸的是,不,这是不正确的。

让我们假设一个“最佳情况”场景, k = n ,所有初始数组的大小< strong> k ,这将是最好的分区。为简单起见,我们还假设 n 是2的幂。

由于假设CPU线程可用性,每次迭代完全并行,因此第一次迭代将具有 O(k + k) 的时间复杂度(这与O相同) (k),但坚持)。

第二次迭代将在2 x k 数组上“工作”,因此时间复杂度 O(2k + 2k) < / strong>,下一次迭代将是 O(4k + 4k) ,直到最后一次迭代,其时间复杂度为 O( n / 2 k + n / 2 k) 考虑到最后你合并最后两个部分并创建完整数组的事实,这是非常期待的。

让所有迭代求和:* 2k + 4k + 8k + ... + nk = O(nk)

你不能低于 nk ,因为你必须在最后创建一个完整的数组,所以 k log(n)是不可能的。