我对时间复杂性问题完全陌生。我正在为Codility练习编写Python代码,我编写的代码返回时间错误,时间复杂度为O(N * N)。预期的时间复杂度是O(N)。
给出一个整数列表A
,
我正在尝试为A[0:i]
中的所有索引A[i:]
计算i
之和与A
之和之间的最小差异。
这是我的解决方案:
def solution(A):
# write your code in Python 2.7
a=[]
for i in range(1,len(A)):
a.append(abs(sum(A[0:i])-sum(A[i:len(A)+1])))
return min(a)
我尝试通过实施以下
来改进代码import sys
def solution(A):
# write your code in Python 2.7
a=sys.maxint
for i in range(1,len(A)):
temp=abs(sum(A[0:i])-sum(A[i:len(A)+1]))
if temp<a:
a=temp
return a
我仍然有同样的复杂性。我理解abs
步骤需要花费大量时间来计算。如何减少此代码的时间复杂度?是否有直观的方式来查看时间复杂度问题?
答案 0 :(得分:1)
在循环的每次迭代中,
你重新计算索引i
之前的元素总和,
以及索引i
之后的元素总和。
这是低效的,
因为你可以随时积累总和。
suffix = sum(A)
prefix = 0
mindiff = suffix
for a in A:
prefix += a
suffix -= a
mindiff = min(mindiff, abs(prefix - suffix))
return mindiff
您的代码也存在其他问题:
A[i:len(A)+1]
中的结束索引超出了A
的范围,这使得阅读容易混淆,并且它表明您可能对Python中的列表索引感到困惑。这应该是A[i:len(A)]
,甚至更好,只需A[i:]
。是否有直观的方式来查看时间复杂性问题?
绝对。
这里的直觉是计算一系列值的总和,
你需要迭代它们。
那就是O(N)
就在那里。
如果这是在另一个O(N)
循环内,
然后整体复杂性变为O(N*N)
。
你的错误忽视了总结的成本。