7
  1. 在给定的数组中,如何找到第二个、第三个、第四个或第五个值?

  2. 另外,如果我们max()在 python 中使用该函数,那么复杂度的顺序是什么,即与此函数相关联max()

.

def nth_largest(li,n):   
    li.remove(max(li))
    print max(ele)  //will give me the second largest
    #how to make a general algorithm to find the 2nd,3rd,4th highest value
    #n is the element to be found  below the highest value
4

6 回答 6

15

我会去:

import heapq
res = heapq.nlargest(2, some_sequence)
print res[1] # to get 2nd largest

这比对整个列表进行排序,然后取前n许多元素更有效。有关更多信息,请参阅heapq 文档

于 2013-08-31T15:34:50.267 回答
4

你可以使用sorted(set(element))

>>> a = (0, 11, 100, 11, 33, 33, 55)
>>>
>>> sorted(set(a))[-1] # highest
100
>>> sorted(set(a))[-2] # second highest
55
>>>

作为一个函数:

def nth_largest(li, n):
    return sorted(set(li))[-n]

测试:

>>> a = (0, 11, 100, 11, 33, 33, 55)
>>> def nth_largest(li, n):
...     return sorted(set(li))[-n]
...
>>>
>>> nth_largest(a, 1)
100
>>> nth_largest(a, 2)
55
>>>

请注意,这里您只需要对重复项进行一次排序和删除,如果您担心性能,您可以缓存sorted(set(li)).

于 2013-08-31T15:38:14.380 回答
2

如果性能是一个问题(例如:您打算经常调用它),那么您绝对应该始终保持列表的排序和重复数据删除,并且只保留第一个、第二个或第 n 个元素(即o(1))。

为此使用该bisect模块 - 它比“标准”更快sort

insort让您插入一个元素,并bisect让您确定是否应该插入(以避免重复)。


如果不是,我建议更简单:

def nth_largest(li, n):.
    return sorted(set(li))[-(n+1)]

如果反向索引对您来说很难看,您可以这样做:

def nth_largest(li, n):
    return sorted(set(li), reverse=True)[n]    
于 2013-08-31T15:33:29.837 回答
2

至于哪种方法的时间复杂度最低,这在很大程度上取决于您计划进行哪种类型的查询。

如果您计划对高索引进行查询(例如,具有 38 个元素的列表中的第 36 个最大元素),您的函数nth_largest(li,n)将具有接近 O(n^2) 的时间复杂度,因为它必须执行最大值,即 O( n),数次。它将类似于选择排序算法,除了使用max()而不是min()

另一方面,如果您只进行低索引查询,那么您的函数可能会很高效,因为它只会应用 O(n)max函数几次,时间复杂度将接近 O(n)。但是,可以在线性时间 O(n) 内构建最大堆,并且最好只使用它。在你经历了构建堆的麻烦之后,你在堆上的所有max()操作都将是 O(1),这对你来说可能是一个更好的长期解决方案。

我相信最可扩展的方法(就能够查询任何n 的第 n 个最大元素而言)是使用内置sort函数对时间复杂度 O(n log n) 的列表进行排序,然后从排序的列表。当然,这不是最节省内存的方法,但就时间复杂度而言,它非常有效。

于 2013-08-31T16:09:34.583 回答
0

如果您不介意使用 numpy ( import numpy as np):

np.partition(numbers, -i)[-i]

为您提供列表中i个最大的元素,并保证最坏情况的O(n)运行时间

这些partition(a, kth)方法返回一个数组,其中第kth 个元素与排序数组中的相同,前面的所有元素都较小,后面的所有元素都较大。

于 2017-04-02T17:09:48.920 回答
-1

怎么样:

sorted(li)[::-1][n]
于 2013-08-31T15:33:06.973 回答