这些代码在不使用循环语句的情况下给出列表中偶数整数的总和。我想知道两个代码的时间复杂性和空间复杂性。哪个最好?
代码1:
class EvenSum:
#Initialize the class
def __init__(self):
self.res = 0
def sumEvenIntegers(self, integerlist):
if integerlist:
if not integerlist[0] % 2:
self.res += integerlist[0]
del integerlist[0]
self.sumEvenIntegers(integerlist)
else:
del integerlist[0]
self.sumEvenIntegers(integerlist)
return self.res
#main method
if __name__ == "__main__":
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even = EvenSum()
print even.sumEvenIntegers(l)
代码2:
import numpy as np
def sum_of_all_even_integers(list):
list_sum = sum(list)
bin_arr = map(lambda x:x%2, list)
return list_sum - sum(list*bin_arr)
if __name__ == "__main__":
list = np.array([1,2,3,4,5,6,7,8,9,10])
print sum_of_all_even_integers(list)
答案 0 :(得分:2)
根据Python wiki,从列表中删除项目需要线性时间与列表中的元素数量成比例。由于您删除了列表中的每个项目,并且每次删除都需要线性时间,因此整个运行时间与列表中项目数的平方成正比。
在您的第二个代码段中,sum
和map
都需要线性时间。因此总体复杂度与列表中元素的数量成线性比例。有趣的是,sum_of_elements
根本没有使用(但它并没有对所有偶数元素求和)。
答案 1 :(得分:1)
第一个代码使用列表中的项删除和递归,python不太好的两件事:时间删除花费O(n)时间,因为你重新创建整个列表,而python不优化递归调用(保持关于追溯的完整信息我认为。)
所以我会选择第二个代码(我认为实际使用#34; for循环"只有循环隐藏在reduce
和map
中)。
如果您使用numpy,您实际上可以执行以下操作:
a = np.array([1,2,3,4,5,6,7,8,9,10])
np.sum(np.where((a+1)%2,a,0))
或者像anki提议的那样:
np.sum( a[a%2 == 0] )
我认为这是最好的,因为numpy针对数组操作进行了优化。
顺便说一句,永远不要命名对象list
,因为它会覆盖列表构造函数。
编辑:
如果你只想要[0,n]中所有偶数的总和,你就不需要总和或任何东西。有一个数学公式:
s=(n//2)*(n//2+1)
答案 2 :(得分:1)
以下情况怎么样?
import numpy as np
a = np.arange(20)
print np.sum(a[a%2==0])
与两个代码段相比,它看起来要轻得多。
np.arange(998)
的小时间:
Pure numpy:
248502
0.0
Class recursion:
248502
0.00399994850159
List/Numpy one:
248502
0.00200009346008
而且,如果有一个999元素数组,那么你的类运行失败,因为达到了最大递归深度。
答案 3 :(得分:0)
首先具有O(N^2)
时间复杂度和O(N)
空间复杂度。第二个具有O(N)
时间复杂度和空间复杂度。
第一个对阵列中的每个元素使用一个堆栈帧(一个常量但非常大的堆栈存储器)。另外,它为每个元素执行函数,但是每次都删除数组的第一个元素,这是一个O(N)
操作。
第二种情况发生在幕后。 map
函数生成一个与原始大小相同的新列表,此外它还为每个元素调用一个函数 - 直接给出复杂性。类似于reduce
和sum
函数 - 它们对列表中的每个元素执行相同的操作,尽管它们不使用比常量更多的内存。添加这些不会使复杂性变得更糟 - 两次或三次O(N)
仍然是O(N)
。
最好的可能是后者,但又一次 - 这取决于你的偏好。也许你想要消耗大量的时间和堆栈空间?在这种情况下,第一个更适合您的喜好。
另请注意,第一个解决方案会修改输入数据 - 换句话说,它们不会执行相同的操作。在调用第一个之后,发送给函数的列表将为空(这可能是也可能不是坏事)。