您将获得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是数组的数量。
这是对的吗?
答案 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)是不可能的。