我正在尝试解决算法问题,请考虑以下列表:
l = [100, 20, 50, 70, 45]
在这个问题中,我必须找到直到索引i的元素的平均值:
i = 0
100
i = 1
(100 + 20) //2 = 60
i = 2
(100+20+50) // 3 = 56
...
最终结果应存储在列表中:
[100, 60, 56, 60, 57]
这是到目前为止的代码:
from functools import reduce
def meanScores(l):
def av(x):
return reduce(lambda a, b: a+b,x)//len(x)
return [av(l[:i]) for i in range(1,len(l)+1)]
效果很好,问题是提交时遇到了时间限制。我认为问题是for循环,因为len(l)
超过一万时会花费很多时间。以前,我使用sum()
进行平均,但是也花费了很多时间,当我将sum()
转换为reduce(lambda a, b: a+b,x)//len(x)
时,算法变得更快了(它解决了更多的测试用例)。如果不是使用for循环,而是使用另一个函数(例如lambda),则问题得以解决。那么您认为有办法吗?谢谢您的时间。
答案 0 :(得分:3)
这是因为每次都对整个数组求和,所以成本是二次的,但是如果每次都重复使用以前的结果,则成本可能是线性的。考虑一下。
答案 1 :(得分:2)
您可以尝试使用numpy.cumsum
并获得平均值除以汇总列表的index + 1。
import numpy as np
l = [100, 20, 50, 70, 45]
l_cumsum = np.cumsum(l)
l_indices = np.arange(1,len(l)+1,1)
l_average = np.divide(l_cumsum, l_indices).tolist()
print(l_average) # Outputs [100.0, 60.0, 56.666666666666664, 60.0, 57.0]
应该很快,O(n),因为numpy.cumsum
已经非常优化。如果仍然希望更快,则可以对其进行多线程处理。
答案 2 :(得分:1)
您想要做的就是在列表中仅迭代一次:
i = [10,20,30,40,50,60,70]
def meanScores(l):
if len(l) == 0: #Check is its an empty list
return []
res = [l[0]] #the first item is the first item in both lists(l)):
res.append(float((res[i-1]*i + l[i])) / (i+1)) #Use the previous result to calculate the new result
return [int(x) for x in res]
对于使用先前的结果,我采用先前的总和(即上一个平均值* i),将新的数字相加,然后除以i + 1。
答案 3 :(得分:1)
一些想法:
av
函数时,都会减少整个列表。自从您在列表理解中调用av
以来,您拨打av
的次数比您需要的次数多。您应该只计算一次汇总列表(使用av
),并在遍历l
时得出汇总。i
,因此不应减少整个列表。您应该先切片第一个列表l[:i]
,然后对缩短的列表运行reduce()
。答案 4 :(得分:1)
由于完整的解决方案已经破坏了游戏,因此O(n)中的方法可行。
请注意,您通常可以避免自己在Python中操纵索引。在这里,我们可以使用enumerate
(起始值为1)来跟踪求和的值的数量。
def means(lst):
sum = 0
out = []
for n, new_val in enumerate(lst, 1): # we enumerate starting with n=1
sum += new_val
out.append(sum/n)
return out
一些测试:
lst = [100, 20, 50, 70, 45]
print(means(lst))
# [100.0, 60.0, 56.666666666666664, 60.0, 57.0]
print(means([]))
# []
答案 5 :(得分:1)
可以用线性时间复杂度即O(n)来实现。下面的示例只是为了给您一个想法,您将如何做。
l = [100, 20, 50, 70, 45]
a = [0] * len(l)
a[0] = l[0]
temp = a[0]
for i in range(1, len(l)):
a[i] = (temp + l[i]) / (i + 1)
temp = temp + l[i]
print(a)
Output [100, 60.0, 56.666666666666664, 60.0, 57.0]