【问题标题】:What is the time complexity of the following merge algorithm?以下合并算法的时间复杂度是多少?
【发布时间】:2017-10-02 18:59:10
【问题描述】:

给你int[][] lists(一个排序的整数数组)。 你要合并所有这些。 时间复杂度是多少?

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

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 是数组的数量。

这对吗?

【问题讨论】:

  • 你是说 DoMerge 的 O(n1+n2) 吗?你写了 O(n1*n2)。
  • 是的,“n1+n2”,对不起,错字
  • 如果您在 non-deterministic Turing machine 上运行代码,那么 O(log(n) k) 是正确的(它可以并行运行无限数量的线程并且没有创建新线程的开销。 ) 当然,在真机上,一旦线程数大于物理 CPU 数,您很快就会遇到瓶颈,之后我们将回到 O(log(n) n) 渐近时间复杂度。

标签: algorithm merge parallel-processing time-complexity


【解决方案1】:

很遗憾,这是不正确的。

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

由于假设 CPU 线程可用性,每次迭代都是完全并行的,因此第一次迭代的时间复杂度为 O(k+k)(这与 O (k),但请稍等)。

第二次迭代将在大小为 2 x k 的数组上“工作”,因此时间复杂度为 O(2k + 2k),下一次迭代将是 O(4k + 4k),直到最后一次迭代的时间复杂度为 O( n/2 k + n/2 k) 考虑到最终合并最后两个部分并创建完整数组这一事实,这是完全可以预料的。

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

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

【讨论】:

  • 感谢您的回答。我这里有点慢,你能解释为什么 "2k + 4k + 8k + ... + nk" 等于 knlog(n) 吗?据我所知,几何级数的总和是 k(2 + 2^2 + ...+2^i) (假设 n = 2^i),这将产生 k.n
  • 我的意思是,我真的很困惑为什么它变成了 k.nlog(n) 而不是 k.n
  • @OneTwoThree - 你是对的......当我最初写这篇文章时为时已晚 - 但现在答案已得到纠正
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2023-03-11
  • 2020-11-15
  • 2019-05-08
  • 1970-01-01
  • 2019-05-14
相关资源
最近更新 更多