最小堆比。排序以查找数组中的第K个最小整数

时间:2017-03-03 05:25:46

标签: algorithm data-structures

我遇到的问题类似于 Given a million integers, return the kth smallest element。问题下面有一个给定的解决方案,我不确定为什么这是一个最佳解决方案。给定的解决方案涉及使用最小堆。所以最初,我认为这是有道理的,因为我们可以在恒定的时间内找到堆中的最小元素。但是在我想了一会儿之后,我想到了将数组中的元素插入堆中的成本。如果我的理解是正确的,插入是O(logN)操作。但是,如果我们要插入N元素,那么这应该花费我们O(NlogN)时间。我们还使用了我们正在使用的堆的额外空间。所以我的问题是,为什么这是一个比排序数组更好的解决方案,并采用kth-1索引?

4 个答案:

答案 0 :(得分:3)

在min heap中,在最坏的情况下单个插入是O(logN) ,因为只有在堆属性(父值应小于子节点)时才会产生成本被侵犯了。

有一个定理说,如果要将数组转换为堆(称为构建堆),则总体复杂度为O(N),而不是{{1 }}。您可以在Wikipedia for binary heap中阅读详细信息。

所以这种方法确实比简单地整理整个数组更好。由于对整个数组进行排序的时间复杂度为O(NlogN),因此使用最小堆方法时,总复杂度为O(NlogN),这在O(N+klogN)较小时更为理想。

为了完整起见,我将描述为什么使用min-heap获取k个最小元素的复杂性为k。如果你想要最小的元素,你可以在恒定的时间内取根。但是第二个最小元素呢?然后,您需要删除最小的元素,然后恢复堆属性。然后根将是数组中删除了最小元素的最小元素,因此它是第二个最小元素。我们可以继续O(N+klogN)次这样做以获得k个最小的元素。由于恢复堆属性的操作为k,因此构建堆的总复杂度为O(logN),然后继续删除最小元素O(N+klogN)次。

答案 1 :(得分:1)

解决此问题的更好方法是使用max-heap of size K。 我们可以遍历并比较数组的每个元素和最大堆的根,如果数组元素小于根,我们可以用元素替换root并堆化堆。此操作将花费log(K)时间。我们将对数组的所有N元素执行此操作。

堆的根将为您提供Kth最小元素。

这样,时间复杂度就会变为O(NlogK)

答案 2 :(得分:1)

问题必须讨论整数的范围。

比如说范围是[0,10000]意味着有重复。现在,如果我们使用排序,那么我们将需要排序一百万个整数!这将是O(nlogn)

在堆的情况下,由于重复由计数器(或链表)处理,我们在堆中只有一个10000元素!一般来说,对于n范围内的[0,m]个整数,堆将O(mlogm)时间m < n。因此堆将是有效的。还有一件事,BUILD_HEAP算法不会使O(mlogm)构建堆。这需要O(m)时间。

当您将kth元素插入堆时,HEAPFY将O(logk)带到k < m。 详细了解here

是的,存在O(n)算法来查找数组中的第k个最小元素。它被称为selection algorithm。 CLRS非常优雅地讨论它。阅读herehere

因此,取决于您是否根据mn

使用选择算法或堆

答案 3 :(得分:1)

首先让我们看看我们有什么选择。

第一个选项是sort和return第k个元素。 如果您可以对输入数组进行排序,则时间复杂度为O(n log n),空间复杂度为O(1)。

第二个选项是维护一个大小为k的堆。它在justhalf's answer中进行了解释。 时间复杂度为O(n log k),空间复杂度为堆的O(k)。

实际上,您可以在O(n)时间内堆积数组,然后弹出k个元素以找到第k个元素。 时间复杂度再次为O(n + k log n),空间复杂度为O(1)。

正如rcgldr的评论所指出的,有一种选择算法,其中O(n)时间和O(1)空间。

  

快速选择是查找第k个最小元素的常用方法。另一种选择是介绍选择。 - rcgldr

所以这取决于具体情况。例如,当使用sort比较使用堆和解决方案的解决方案时,您需要考虑k将是什么。有时k非常小,使用堆可能会有所帮助。

有时输入是一个流,你需要实时报告第k个元素,使用O(n log n)时间对数组进行排序,或者在O(n)时间内使用选择算法可能太慢。如果你使用堆,你可以在O(1)时间内得到答案。

您还需要考虑空间复杂性。 有时您可能不允许更改输入,因此如果使用排序或选择算法,则需要复制数组。它意味着O(n)空间与堆解的O(k)空间相比。

所以这完全取决于。你能改变输入数组吗?你可以花多少钱?这是一个实时查询以及查询的频率吗?输入是增长还是静止?在不同情况下,更好的解决方案会有所不同。