在线性时间内准备数组以找到O(k)中的k个最小元素

时间:2013-06-23 13:47:19

标签: algorithm sorting big-o

这是我在网上发现的一个有趣的问题。给定一个包含n个数字的数组(没有关于它们的信息),我们应该以线性时间预处理数组,以便我们可以返回 k中的O(k)个最小元素时间,当我们得到一个数字1 <= k <= n

我和一些朋友一直在讨论这个问题,但没有人能找到解决方案;任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:14)

对于预处理步骤,我们将在同一数据集上多次使用基于分区的选择。

使用算法找到 n / 2 -th数字。现在数据集被分为两半,一半,一半。在下半部再次找到中点。在它的下部分区做同样的事情等等......总的来说这是O(n)+ O(n / 2)+ O(n / 4)+ ... = O(n)。

现在,当您必须返回 k 最小元素时,请搜索最近的 x &lt; k ,其中 x 是分区边界。可以返回它下面的所有内容,并且从下一个分区返回 k - x 数字。由于下一个分区的大小为 O(k),因此为 k - x 编号运行另一个选择算法将返回其余分区。

答案 1 :(得分:1)

我们可以在线性时间内找到列表和分区的中位数。

然后我们可以使用以下算法:维护大小为2k的缓冲区。

每次缓冲区变满时,我们会找到它周围的中位数和分区,只保留最低的k元素。
这需要n/k查找中位数和分区步骤,每个步骤在传统的快速选择中花费O(k)时间。这种方法只需要O(n)次。

另外如果您需要排序的输出。 这会增加额外的O(k log k)时间。总的来说,此方法仅需要O(n + k log k)时间和O(k)空间。

相关问题