在不排序的情况下找出无序列表的第N项
你好。我有一个非常大的数组,我想找出第N个最大的值。简单来说,我可以先把这个数组排序,然后取出第N个元素,但因为我只对一个元素感兴趣,所以可能有比排序整个数组更好的方法……
11 个回答
4
一种简单的改进版快速排序在实际应用中效果很好。它的平均运行时间和数据量N成正比(不过在最坏的情况下,可能会遇到O(N^2)的糟糕运行时间)。
操作方式和快速排序类似。首先随机选择一个基准值,然后遍历你的数据,看看每个值是高于还是低于这个基准值,然后根据这个比较把它们放进两个箱子里。在快速排序中,你会递归地对这两个箱子进行排序。但在计算第N个最大值时,你只需要对其中一个箱子进行排序。每个箱子里的数据量可以告诉你哪个箱子里有你要找的第N个最大值。举个例子,如果你想找第125个最大值,而你把数据分成了两个箱子,其中“高”箱子有75个值,“低”箱子有150个值,那么你可以忽略“高”箱子,直接去找“低”箱子里的第125-75=50个最大值。
21
堆是一种非常适合这个操作的数据结构,而Python有一个很棒的内置库可以用来处理堆,叫做heapq。
import heapq
def nth_largest(n, iter):
return heapq.nlargest(n, iter)[-1]
使用示例:
>>> import random
>>> iter = [random.randint(0,1000) for i in range(100)]
>>> n = 10
>>> nth_largest(n, iter)
920
通过排序来确认结果:
>>> list(sorted(iter))[-10]
920