如果我有n个整数,是否可以在O(k + logn)时间内列出n个值中的k个最大元素?我得到的最接近的是构造一个最大堆并提取最多k次,这需要O(klogn)时间。还考虑使用inorder遍历。
答案 0 :(得分:3)
解决这个问题的方法。
对数据进行排序,然后选择前k个。排序需要O(n lg n)
并且迭代顶部k需要O(k)
。总时间:O(n lg n + k)
从数据构建最大堆并删除前k次。构建堆是O(n)
,删除顶部项目的操作是O(lg N)
以重新合并。总时间:O(n) + O(k lg n)
保持最小大小为k的正在运行的最小堆。迭代所有数据,添加到堆中,然后获取整个堆。总时间:O(n lg k) + O(k)
使用选择算法查找第k个最大值。然后迭代所有数据以查找大于该值的所有项目。
一个。您可以使用QuickSelect查找最大的k,其平均运行时间为O(n)
,但最差情况为O(n^2)
。总平均个案时间:O(n)
+ O(n)
= O(n)
。总的最坏情况时间:O(n^2) + O(n) = O(n^2)
。
湾您还可以使用median-of-medians算法找到最大的k',这些算法的最差运行时间为O(n)
,但不是就地。总时间:O(n)
+ O(n)
= O(n)
。
答案 1 :(得分:0)
您可以使用分而治之技术从数组中提取第k个元素。技术有时被称为快速选择,因为它使用了 Quicksort 的理念强>
QuickSort ,我们选择一个pivot
元素,然后将pivot元素移动到正确的位置,并将partition
周围的数组移动。这个想法是,不要完成快速排序,但要停止在枢轴本身是最小元素的位置。此外,不要重复枢轴的左右两侧,而是根据枢轴的位置重复其中一个。此方法的最差情况时间复杂度为 O(n^2)
,但它平均可用于 O(n)
。
答案 2 :(得分:-1)
构造堆需要O(nlogn),并且提取k个元素需要O(klogn)。如果你得出结论提取k个元素是O(klogn),那就意味着你并不担心构建堆所需的时间。
在这种情况下,只需对列表进行排序(O(nlogn))并取k个最大元素(O(k))。