试图计算一些简单代码的时间复杂度,但我不知道在求和子数组时如何计算时间复杂度。代码如下:
for i=1 to n {
for j = i+1 to n {
s = sum(A[i...j])
B[i,j]=s
}}
所以我知道嵌套的for循环不可避免地给我们一个O(n ^ 2),我相信求和子数组的函数也是O(n ^ 2)。但是,我认为整个算法的时间复杂度为O(n ^ 3)。如何获得此信息?谢谢!
答案 0 :(得分:1)
我喜欢将for循环视为求和。因此,步骤数(写为函数T(n)
)为:
T(n) = \sum_{i=1}^n numStepsInInnerForLoop
在这里,我使用的是用伪MathJax编写的东西,并编写了外部for循环,作为内部for循环中步数从i=1
到n
的总和(从i+1
到n
中的一个)。您可以类似地认为这是对内部for循环中从i=1
到n
的步数求和。替换为numStepsInInnerForLoop
会导致:
T(n) = \sum_{i=1}^n [\sum_{j=i+1}^n numStepsOfSumFunction]
此函数现在表示将两个for循环充实为总和的步骤数。假设s = sum(A[i...j])
迈出了j-i+1
步而B[i,j]=s
迈出了一步,我们可以将numStepsOfSumFunction
替换为这些更有用的参数,等式现在变为:
T(n) = \sum_{i=1}^n [\sum_{j=i+1}^n (j-i+1 + 1)]
求解这些求和时(使用在this summation tutorial page上看到的那种公式),您将获得T(n)
的三次函数,该函数对应于O(n^3)
。
答案 1 :(得分:0)
您的推理使我相信您正在n大小的数组上运行此算法。如果是这样,那么每次在内部for循环中调用sum
方法时,都会在特定值范围(索引i到j)上调用此方法。对于此for循环的每个迭代,此sum
方法将迭代1,2,3,...,然后随着j从(i + 1)增加到n,最终在最后一次迭代中迭代n个元素。请注意,这是当i = 1时。随着i的增加,它不必再从1,2,3,...变为n,因为从技术上讲它将上升到n-i个元素。不过,大O是最坏的情况,因此我们必须使用这种情况。
1 + 2 + 3 + ... + n给我们n ^ 2。 sum
方法的运行时间取决于i和j的值;但是,在给定条件下在for循环中运行时,内部for循环的一次迭代中对sum
的所有调用的总时间复杂度为O(n ^ 2)。最后,由于该内部for循环执行了n次,因此整个算法的总时间复杂度为O(n ^ 3)。