gpt4 book ai didi

python - 如何有效地找到最小长度的峰?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:10:42 24 4
gpt4 key购买 nike

我有一个整数列表/数组,如果它上升然后下降,则称子数组为峰值。例如:

[5,5,4,5,4]

包含

[4,5,4]

这是一个高峰。

还考虑

[6,5,4,4,4,4,4,5,6,7,7,7,7,7,6]

其中包含

[6,7,7,7,7,7,6]

这是一个高峰。

问题

给定一个输入列表,我想找到其中包含的所有最小长度的峰并报告它们。在上面的示例中,[5,6,7,7,7,7,7,6] 也是一个峰值,但我们删除了第一个元素,它仍然是一个峰值,因此我们不报告

因此对于输入列表:

L = [5,5,5,5,4,5,4,5,6,7,8,8,8,8,8,9,9,8]

我们会回来的

[4,5,4] and [8,9,9,8] only.

我在为此设计一个不错的算法时遇到了问题。任何帮助将不胜感激。

最佳答案

使用itertools

这是一个使用 itertools.groupby 的简短解决方案检测峰值。然后将识别峰的组解包以产生实际序列。

from itertools import groupby, islice

l = [1, 2, 1, 2, 2, 0, 0]

fst, mid, nxt = groupby(l), islice(groupby(l), 1, None), islice(groupby(l), 2, None)
peaks = [[f[0], *m[1], n[0]] for f, m, n in zip(fst, mid, nxt) if f[0] < m[0] > n[0]]

print(peaks)

输出

[[1, 2, 1], [1, 2, 2, 0]]

使用循环(更快)

上面的解决方案很优雅,但是由于创建了三个 groupby 实例,所以列表被遍历了三次。

这是一个使用单次遍历的解决方案。

def peaks(lst):
first = 0
last = 1
while last < len(lst) - 1:
if lst[first] < lst[last] == lst[last+1]:
last += 1
elif lst[first] < lst[last] > lst[last+1]:
yield lst[first:last+2]
first = last + 1
last += 2
else:
first = last
last += 1

l = [1, 2, 1, 2, 2, 0, 0]
print(list(peaks(l)))

输出

[[1, 2, 1], [1, 2, 2, 0]]

基准测试说明

在使用 timeit 进行基准测试时,我注意到使用循环的解决方案的性能提高了大约 20%。对于短列表,groupby 的开销可能会使该数字高达 40%。基准测试是在 Python 3.6 上完成的。

关于python - 如何有效地找到最小长度的峰?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54673528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com