我想添加另一种更普遍的方法:
以下是一种递归查找给定数字列表中第i个最小值的方法
def find_i_minimums(numbers,i):
minimum = float('inf')
if i==0:
return []
less_than_i_minimums = find_i_minimums(numbers,i-1)
for element in numbers:
if element not in less_than_i_minimums and element < minimum:
minimum = element
return less_than_i_minimums + [minimum]
例如,
>>> find_i_minimums([0,7,4,5,21,2,6,1],3)
[0, 1, 2]
(如果你只想要第i小的数,你需要提取列表的最终值)
尽管上述算法的时间复杂度很差,为O(N*i^2)(因为递归深度为i,在每个递归调用中我们会遍历长度为N的'numbers'列表中的所有值,并检查我们正在搜索的最小元素是否不在长度为i-1的列表中,因此总复杂度可以用一个几何级数来描述,它将给出上述提到的复杂度)。
这里有一个类似但另一种实现方法,其平均时间复杂度为O(N*i),它使用了Python内置的'set'数据结构:
def find_i_minimums(numbers,i):
minimum = float('inf')
if i==0:
return set()
less_than_i_minimums = find_i_minimums(numbers,i-1)
for element in numbers:
if element not in less_than_i_minimums and element < minimum:
minimum = element
return less_than_i_minimums.union(set({minimum}))
如果你的'i'很小,你可以使用上面的实现,然后提取你想要的最小值(或者如果你想要第二个最小值,在你的情况下运行i=2的代码,然后只需从输出数据结构中提取最后一个元素)。
但是,如果'i'比log(N)大,我建议对数字列表进行排序(例如,使用归并排序,其复杂度在最坏情况下为O(N*log(N))),然后取第i个元素。为什么呢?因为如上所述,上述算法的运行时间对于较大的'i'值不太理想。
sorted(numbers)[1]
这样的代码可能更可取。 - Tim Pietzckerheapq
。 - Tim Pietzcker