我这里有一个算法。
Click here to check algorithm image
它做什么,它遍历一个数组并找到3个最大值并返回它们的总和。 例如,数组[1,2,3,4,5]将返回12(3 + 4 + 5 = 12)。
图像中的算法表明它是O(nlogk)。但那是我无法理解的。
以下是关于图像中第一个for循环的观点:
Heap's method" insert()"和" deleteMin()",它们都需要O(logn)。所以在第一个for循环中,它通过添加运行时生成O(2 * logn),这就是O(logn)。由于第一个for循环遍历数组中的所有元素,因此第一个for循环的总运行时间为O(nlogn)。
以下是我对图片中第二次循环的看法:
从上一个for循环开始,如果h.size()>我们删除了一些最小值。 ķ。所以堆中的值的数量目前是k。 "总和=总和+ h.min()"需要O(logn),因为如果我知道的话,在堆中搜索最小值需要O(logn),并且" h.deleteMin()"也需要O(logn),因为它必须再次搜索并删除。 O(2 * logn)通过添加它们的运行时也是如此,它只是O(logn)。因为我们迭代这个while循环只有k次,因为有k个元素,所以第二个while循环导致O(k * logn)
所以我们从第一个for循环获得O(nlogn),从第二个while循环获得O(k logn)。显然O(nlogn)大于O(k logn),因为k是一些常数。因此,该算法最终以O(nlogn)结束。
但答案是" O(nlogk)"而不是" O(nlogn)"。
你能解释一下原因吗?
答案 0 :(得分:1)
堆上的操作需要O(log(size_of_heap))
。在此算法的情况下,堆大小为k
(不包括前几次迭代)。
所以我们得到O(total_number_of_elements*log(size_of_heap))=O(n*log(k))
。
答案 1 :(得分:0)
关于insert()和deletemin()运行时的假设需要O(log n)是不正确的。 ' n' in O(log n)表示堆中的no.of元素。在这种情况下,它是k。
因此,对于第一个循环 - 每个元素都有O(2 * logk),总数将有O(n logk)和第二个循环 - O(k logk) 总复杂度可以定义为O(n * logk)