这个算法的运行时间是多少? (递归Pascal的三角形)

时间:2014-02-25 20:14:56

标签: algorithm recursion big-o

给出以下功能:

Function f(n,m)
   if n == 0 or m == 0: return 1
   return f(n-1, m) + f(n, m-1)

f的运行时复杂性是多少?我知道如何快速和肮脏,但如何正确表征它?是O(2^(m*n))吗?

3 个答案:

答案 0 :(得分:6)

这是Pascal三角形的一个实例:每个元素都是它上面两个元素的总和,两边都是一个。

所以f(n, m) = (n + m)! / (n! . m!)

现在要知道计算f所需的f(n, m)调用次数,您可以构造一个修改过的Pascal三角形:而不是上面元素的总和,考虑1 + sum(自称加上两个递归调用。)

绘制修改后的三角形,您将很快说服自己这完全是2.f(n, m) - 1

您可以从斯特林的近似中获得二项式系数的渐近行为。 http://en.wikipedia.org/wiki/Binomial_coefficient#Bounds_and_asymptotic_formulas

f(n, m) ~ (n + m)^(n + m) / (n^n . m^m)

答案 1 :(得分:5)

f(n, m)的运行时在O(f(n, m))。通过以下观察可以很容易地验证这一点:

Function g(n, m):
    if n=0 or m=0: return 1
    return g(n-1, m) + g(n, m-1) + 1

函数f的调用频率与g相同。此外,函数g被称为g(n, m)次,以评估g(n, m)的结果。同样,函数f的确称为g(n, m) = 2*f(n, m)-1次,以便评估f(n, m)的结果。

正如@Yves Daoust在他的回答f(n, m) = (n + m)!/(n!*m!)中指出的那样,因此O((n+m)!/(n!*m!))得到f的非递归运行时。

答案 2 :(得分:-1)

了解递归函数

f(n, 0) = 1
f(0, m) = 1
f(n, m) = f(n - 1, m) + f(n, m - 1)

对我来说,这些值看起来像Pascal triangle

   n 0  1  2  3  4 ..
 m

 0   1  1  1  1  1 ..
 1   1  2  3  4
 2   1  3  6
 3   1  4     .
 4   1           .
 .   .
 .   .

求解递归方程

Pascal三角形的值可以表示为binomial coefficients。翻译坐标得到f:

的解决方案
f(n, m) = (n + m) 
          (  m  )
        = (n + m)! / (m! (n + m - m)!) 
        = (n + m)! / (n! m!)

这是一个在n和m两个参数中对称的好词。 (@Yves Daoust在本次讨论中首先给出的最后一个词)

Pascal的规则

f的递归方程可以通过使用二项式系数的对称性导出Pascal's Rule

f(n, m) = (n + m)
          (  n  )
        = (n + m)
          (  m  )
        = ((n + m) - 1) + ((n + m) - 1)
          (      m    )   (    m - 1  )
        = ((n - 1) + m) + (n + (m - 1))
          (     m     )   (    m      )
        = f(n - 1, m) + f(n, m - 1)

确定呼叫次数

" f"的呼叫次数计算函数F类似于f,我们只需要添加对f本身的调用和两个递归调用:

F(0, m) = F(n, 0) = 1, otherwise

F(n, m) = 1 + F(n - 1, m) + F(n, m - 1)

(在本次讨论中首先由@blubb提供)。

了解呼叫数量函数

如果我们写下来,我们会得到另一个三角形方案:

 1  1  1  1  1 ..
 1  3  5  7
 1  5 11
 1  7     .
 1           .
 .
 .

按值比较三角形值,一个猜测

F(n, m) = 2 f(n, m) - 1  (*)

(@blubb在本次讨论中首先提出的结果)

证明

我们得到了

F(0, m) = 2 f(0, m) - 1  ; using (*)
        = 1              ; yields boundary condition for F 

F(n, 0) = 2 f(n, 0) - 1 
        = 1

应该并检查其他条款,我们看到了

F(n, m) = 2 f(n, m) - 1                                   ; assumption
        = 2 ( f(n - 1, m) + f(n, m - 1) ) - 1             ; definition f
        = 1 + (2 f(n - 1, m) - 1) + (2 f(n, m - 1) - 1)   ; algebra
        = 1 + F(n - 1, m) + F(n, m - 1)                   ; 2 * assumption

因此,如果我们使用(*)和f的else子句,则F结果的else子句。

作为有限差分方程和F hold的起始条件,我们知道它是F(解的唯一性)。

估计呼叫次数的渐近行为

现在计算/估算F的值(即算法的运行时间)。

作为

F = 2 f - 1

我们看到了

O(F) = O(f).

因此该算法的运行时间为

O( (n + m)! / (n! m!) )

(@Yves Daoust在本次讨论中首先给出的结果)

近似运行时

使用Stirling approximation

n! ~= sqrt(2 pi n) (n / e)^n

一个人可以得到一个没有难以计算因子的形式。一个得到

f(n, m) ~= 1/(2 pi) sqrt((n+m) / (n m)) [(n + m)^(n + m)] / (n^n m^m)

因此到达

O( sqrt((n + m) / (n m)) [(n + m)^(n + m)] / (n^n m^m) )

(使用@Yves Daoust在本次讨论中首次提出的斯特林公式)