我在循环中使用了sum()
,执行过程花费了4秒钟以上的时间,sum()
是否等于嵌套循环?
def arrayMaxConsecutiveSum(inputArray, k):
cop=k
lis=[]
i=0
while i < len(inputArray):
inpu=sum(inputArray[i:cop])
lis.append(inpu)
cop+=1
i+=1
return max(lis)
答案 0 :(得分:4)
sum
被实现为C ++库,因此尽管您仍然以任何一种方式运行嵌套循环,它仍将比Python for循环更快。为了说明这一点,我在这里为您的代码计时,以及使用Python循环代替的修改代码:
def arrayMaxConsecutiveSumLoop(inputArray, k):
cop=k
lis=[]
i=0
while i < len(inputArray) - k:
inpu = 0
for j in range(i, cop): # for-loop in place of sum
inpu += inputArray[j]
lis.append(inpu)
cop += 1
i += 1
return max(lis)
时间是:
arrayMaxConsecutiveSum(np.random.rand(10000), 100)
111 ms ± 1.42 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
arrayMaxConsecutiveSumLoop(np.random.rand(10000), 100)
198 ms ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
因此,sum
(您的版本)的实施速度要快两倍左右!
我使用numpy
重新编写了您的函数,以使其更快地运行!此实现没有嵌套循环,并且是O(n),并且可以通过非常快的numpy库实现。
import numpy as np
def array_max_consecutive_sum(input_array, k):
result = np.cumsum(input_array)
return max(result[k:] - result[:-k])
array_max_consecutive_sum(np.random.rand(10000), 100)
688 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
那快150倍!
顺便说一下,接受的答案(在撰写本文时)给出了时间安排:
6.46 ms ± 147 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
速度快,但仍仅是上述numpy实现速度的十分之一。而且,结果是错误的。
答案 1 :(得分:1)
是的,为了将所有元素加在一起,sum
代码必须遍历inputArray
(从i到cop)。
此外,len(inputArray)
还必须遍历整个数组以获取其长度。因此,您的解决方案是O(n * k)
您可以使用以下方法将代码优化为O(n)解决方案:
def arrayMaxConsecutiveSum(inputArray, k):
max = sum(inputArray[0:k])
bucket = max
count = len(inputArray)
for i in range(1, 1 + count - k):
prev = inputArray[i - 1]
cur = inputArray[i + k - 1]
bucket += cur - prev
if bucket > max:
max = bucket
return max
此算法仅在数组上循环一次。想象一下,有一个固定的铲斗沿一条线滑下。随着i的增加,存储桶需要带走最近的物品,但是最旧的物品会掉下来。使用此逻辑,您只需要将每个项目最多查看两次-将其添加到存储桶中时,以及将其从另一端移出时。
**请注意,为清楚起见,省略了特殊情况的处理**