【发布时间】:2013-01-17 01:31:39
【问题描述】:
for i <- 1 to n
for j <- i to n
for k <- i to j
第二个循环的运行时间的数学表达式是什么?
是n = n^2的j = 1到n之和吗?
由于它同时依赖于 i 和 n,你如何推导出它?
【问题讨论】:
-
绝对是
O(n^3),直观上也是Th(n^3):[i,j,k]的集合由非平行平面界定。
for i <- 1 to n
for j <- i to n
for k <- i to j
第二个循环的运行时间的数学表达式是什么?
是n = n^2的j = 1到n之和吗?
由于它同时依赖于 i 和 n,你如何推导出它?
【问题讨论】:
O(n^3),直观上也是Th(n^3):[i,j,k] 的集合由非平行平面界定。
让我们以两种方式解决这个问题:
如果您需要计算第二个循环运行时函数,则必须将其表示为 n 和 i 的函数。因此,您将修复i,因为它作为常量进入第二个循环,并且您不会在第二个或第三个循环的任何地方更改它的值。如果您想了解为什么第二个循环运行时间取决于i 和n,您可以以等效形式编写您的算法:
for i <- 1 to n
doSomething(i,n)
doSomething(i,n):
for j <- i to n
for k <- i to j
doStuffHere() //
当j=i,doStuff() 只执行一次,因为j=i 和k=j=i,所以循环在仅仅1 次迭代后就停止了。
当j=i+1、doStuff()被执行2次等时
你可以推导出一个规则,对于j的任意值,doStuff()被执行(j-i+1)次,即j=i时执行1次,j=i+1时执行2次,j=i+3时执行3次, ...,当 j=i 时,n-i+1 次。这意味着运行时间函数是:
f(n,i) = 1+2+3+...+(n-i+1) = (n-i+1)*(n-i+1+1)/2 =
= (n-i+1)(n-i+2)/2
稍后,当你尝试推导整个算法的复杂度函数时,你会看到对于从 1 到 n 的每一个 i,你都有 f(n,i)doStuff(),所以整个算法就会运行时间:
RT(n) = f(1,n) + f(2,n) + f(3,n) + .. + f(n,n)
您必须在此处进行一些数学运算并使用公式计算级数总和。但是,还有另一种方法,更优雅,但可能难以理解。
很明显,对于算法中的每个 j 和 k:
i <= j,k <= nk >= j
所以,您的代码实际上是从 [i,n] 中选择两个正整数 j 和 k,其中 j
数学公式的有用链接
【讨论】: