for i <- 1 to n
for j <- i to n
for k <- i to j
第二个循环的运行时间的数学表达式是什么?
是n = n ^ 2的j = 1到n的和?
你是如何得出它的,因为它依赖于i和n?
答案 0 :(得分:1)
让我们以两种方式解决问题:
如果您需要计算第二个循环运行时函数,则必须将其表示为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次,{{1}时为2次当{= 1}}时,3次,...,当j = i时,n-i + 1次。这意味着运行时功能是:
j=i+1
稍后,当您尝试导出整个算法的复杂度函数时,您将看到对于从1到n的每个i,您有f(n,i)j=i+3
,因此整个算法将具有运行时间:
f(n,i) = 1+2+3+...+(n-i+1) = (n-i+1)*(n-i+1+1)/2 =
= (n-i+1)(n-i+2)/2
你必须在这里做一些数学运算并使用公式来表示进展总和。然而,还有另一种方法,更优雅,但也许难以理解。
很明显,对于算法中的每个j和k:
doStuff()
RT(n) = f(1,n) + f(2,n) + f(3,n) + .. + f(n,n)
那么,你的代码所做的实际上是从[i,n]中选择两个正整数j和k,其中j <= k。包含那些对j的集合,k实际上是重复的组合,其中我们从具有重复的n-i + 1个元素中选择两个元素。不要感到困惑,因为在某些选择中,第一个数字不会小于第二个数字。您可以随时切换它们,即以非降序重写它们,然后将第一个视为您的j,将第二个视为您的k。这两个数字可以用(n-i + 1)(n-i + 2)/ 2种方式选择,这就是算法的运行时间函数。通过更多的思考和更少错误的数学计算,您可以以更优雅的方式获得解决方案。 如果您尝试确定整个算法的运行时间函数,则适用相同的逻辑。
与数学公式有用的链接