我知道我可以在几乎线性的时间内使用quickselect得到Kth顺序统计量(即数组中的第k个最小数),但是如果我需要 k的最小元素?
维基百科链接具有单元素查找的伪代码,但不适用于k个最小元素 s 查找。
如何修改quickselect以在线性时间内获得它(如果可能的话)?
答案 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的答案可能在技术上更正确,因此更适合学术目的。