了解python代码的时间复杂度

时间:2017-07-22 10:05:43

标签: python time-complexity

我对时间复杂性问题完全陌生。我正在为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步骤需要花费大量时间来计算。如何减少此代码的时间复杂度?是否有直观的方式来查看时间复杂度问题?

1 个答案:

答案 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)。 你的错误忽视了总结的成本。