使quickselect适应数组中最小的k元素

时间:2015-07-07 13:49:39

标签: arrays algorithm sorting data-structures language-agnostic

我知道我可以在几乎线性的时间内使用quickselect得到Kth顺序统计量(即数组中的第k个最小数),但是如果我需要 k的最小元素

维基百科链接具有单元素查找的伪代码,但不适用于k个最小元素 s 查找。

如何修改quickselect以在线性时间内获得它(如果可能的话)?

2 个答案:

答案 0 :(得分:4)

我相信在您使用quickselest查找k - statictic之后,您将自动发现结果数组的第一个k元素是k个最小元素,仅可能没有排序。

此外,quickselect实际上对k - 统计数据进行了分区k之前的所有元素 - 统计数据都小于(或等于),并且之后的所有元素都更大或相等。这很容易证明。

请注意,例如对于C ++ nth_element

  

其他元素没有任何特定顺序,除外   nth之前的元素都不大于它,并且没有   它后面的元素较少。

如果您不仅需要k个最小元素,而是排序 k个最小元素,您当然可以在快速选择后对它们进行排序。

答案 1 :(得分:3)

实际上不需要修改quickselect。如果我有一个数组(在这个例子中称为arrayToSearch)并且我想要k个最小的项目我会这样做:

int i;
int k = 10;  // if you wanted the 10 smallest elements 
int smallestItems = new Array(k);
for (i = 0; i < k; i++)
{
    smallestItems[i] = quickselect(i, arrayToSearch);
}

编辑:我假设k是一个相对较小的数字,它会产生有效的Big-O O(n)。如果不假设k很小,则其速度为O(k * n),而不是线性时间。我的答案更容易理解,适用于大多数实际目的。 recursion.ninja的答案可能在技术上更正确,因此更适合学术目的。