【问题标题】:Complexity of factorial recursive algorithm阶乘递归算法的复杂度
【发布时间】:2013-04-28 16:37:19
【问题描述】:

今天在课堂上,我的老师在黑板上写下了这个递归阶乘算法:

int factorial(int n) {
   if (n == 1) 
       return 1;
   else 
       return n * factorial(n-1);
}

她说它的成本是T(n-1) + 1

然后用迭代方法她说T(n-1) = T(n-2) + 2 = T(n-3) + 3 ... T(n-j) + j,所以算法在n - j = 1时停止,所以j = n - 1

之后,她将j替换为T(n-j) + j,得到T(1) + n-1

她直接说对于那个n-1 = 2(log2n-1),所以算法的代价是指数级的。

最后两步我真的输了。有人可以向我解释一下吗?

【问题讨论】:

  • 我想分享一个可以使用的旧线程。 Link_TO_Thread
  • 上面写的函数进入了factorial(0)的无限循环。

标签: complexity-theory big-o factorial


【解决方案1】:

让我们开始分析这个算法。我们可以为完成的工作总量写一个递归关系。作为一个基本情况,当算法在大小为 1 的输入上运行时,您会做一个工作单元,所以

T(1) = 1

对于大小为 n + 1 的输入,您的算法在函数本身内执行一个工作单元,然后在大小为 n 的输入上调用相同的函数。因此

T(n + 1) = T(n) + 1

如果你扩展重复的条款,你就会明白

  • T(1) = 1
  • T(2) = T(1) + 1 = 2
  • T(3) = T(2) + 1 = 3
  • T(4) = T(3) + 1 = 4
  • ...
  • T(n) = n

所以一般来说,这个算法需要 n 个工作单元才能完成(即 T(n) = n)。

你的老师接下来说的是

T(n) = n = 2log2 n

这个说法是正确的,因为 2log2x = x 对于任何非零 x,因为取幂和对数是彼此的逆运算。

所以问题是:这是多项式时间还是指数时间?我将其归类为伪多项式时间。如果将输入 x 视为一个数字,则运行时确实是 x 中的多项式。但是,多项式时间是正式定义的,因此算法的运行时间必须是关于用于指定问题输入的位数的多项式。在这里,数字 x 只能以 Θ(log x) 位指定,因此 2log x 的运行时间在技术上被认为是指数时间。我在this earlier answer 中将其写为长度,我建议您查看它以获得更全面的解释。

希望这会有所帮助!

【讨论】:

  • 听起来像Quasi-polynomial time
  • 在这里恢复一个旧线程,但我认为注意老师是正确的可能会有所帮助。因为复杂性是通过输入的“有效”编码来衡量的。 Factorial 有一个单一的 int n 作为输入,其有效编码的大小为log n,而不是n! (另请参阅我的回答:programmers.stackexchange.com/questions/181268/…
  • @A.J.Rouvoet 先生,很抱歉再次提出一个老问题;但是先生,我正在尝试使您使用的这种概念有效编码,您能简要解释一下吗,我只是想了解
猜你喜欢
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2021-05-28
  • 2015-04-19
  • 2017-11-20
  • 1970-01-01
  • 2011-02-12
  • 2015-05-13
相关资源
最近更新 更多