我有一个包含 n 双值的列表,我需要在该列表中找到 k 最低的double值
您会推荐什么算法?
目前我使用 Quicksort 对整个列表进行排序,然后从排序列表中取出第一个 k 元素。我希望应该有一个更快的算法。
感谢您的帮助!!!
答案 0 :(得分:10)
您可以为解决方案建模以匹配nlargest() code in Python's standard library。
算法效率惊人。例如,当n = 100,000且k = 100时,对于随机排列的输入,比较的数量通常约为106,000。这只是略多于100,000次比较,以找到单个最小值。而且,它比整个数据集中的完全快速排序少做二十倍的比较。
各种算法的相对强度在http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest
进行了研究和总结答案 1 :(得分:8)
您可以使用selection algorithm找到第k个最低元素,然后迭代并返回它以及低于它的所有元素。如果列表可以包含重复项,则必须完成更多工作(确保您不会得到所需的更多元素)。
这个解决方案是O(n)
。
选择算法在C ++中实现为nth_element()
另一个替代方法是使用大小为k
的最大heap ,并迭代元素,同时保持堆以容纳所有k个最小元素。
for each element x:
if (heap.size() < k):
heap.add(x)
else if x < heap.max():
heap.pop()
heap.add(x)
完成后 - 堆包含k个最小元素。
此解决方案为O(nlogk)
答案 2 :(得分:2)
从C ++标准库中查看partial_sort算法。
答案 3 :(得分:2)
您可以使用std::nth_element。这是O(N)的复杂性,因为它不对元素进行排序,它只是将它们排列成使得某个N下的每个元素都小于N.
答案 4 :(得分:0)
你可以使用选择排序,需要O(n)来选择第一个最低值。一旦我们在位置1上设置了这个最低值,我们就可以重新扫描数据集以找出第二个最低值。并且可以做到直到我们具有第k个最低值。这样,如果k足够小于n,那么我们将得到复数kn,它相当于O(n)......