我正在尝试查找列表中某个部分的最小元素。在以下示例中,a是开头,b是结束。我希望这些索引包含分区列表,因此如果列表是[1,2,3,9,4,10],索引1到4将包括2和4。
def minimum (a,b,list):
return min(list[a:b])
换句话说,有没有办法让list[a:b]
包容?
答案 0 :(得分:2)
默认情况下,没有。
对于这种情况,更常规的做法是:
min(li[a:b + 1])
还要注意命名变量列表,因为它可能会产生意想不到的后果(静默命名空间问题),因为" list"也命名内置列表容器类型。
如果您只是想编写自己的最小方法,可以使用上述方法将此行为封装在最小方法中,这样您就不必再考虑它了。
附注:标准列表切片使用O(N)空间,如果最小值被称为超过增益,则对于大型列表可能会变得昂贵。更便宜的O(1)空间替代方案是:
def minimum(a, b, li):
min(itertools.islice(li, a, b + 1))
修改: 除非你从列表的开头开始切片或者有严格的内存限制,否则不要使用islice。它首先迭代到a,而不是直接索引到a,这可能需要O(b)运行时。
更好的解决方案是这样的,它运行O(b-a)运行时和O(1)空间:
def minimum(li, a=0, b=None):
if b is None:
b = len(li) - 1
if b - a < 0:
raise ValueError("minimum() arg is an empty sequence")
current_min = li[a]
for index in xrange(a, b + 1):
current_min = min(current_min, li[index])
return current_min
如果列表是静态的(在一系列查询期间不删除和插入元素),您可以使用的更高级解决方案是使用段树执行范围最小查询:http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/
构建树需要O(N)运行时和O(N)空间,尽管之后的所有查询只需要O(log(N))运行时和O(1)额外空间。