【发布时间】:2021-07-28 01:19:47
【问题描述】:
long fib(int n)
{
if (n <= 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
虽然我见过很多不同的解决方案,但其中一些对我来说没有意义。 就像这个非常受欢迎的解决方案一样(我将整个内容粘贴到这里,感谢您的耐心等待,因为这需要一些时间)
让我们首先假设 T(n-2) ≈ T(n-1)。暂时不要担心为什么 - 这很快就会变得明显。
将 T(n-1) = T(n-2) 的值代入我们的关系 T(n),我们得到:
T(n) = T(n-1) + T(n-1) + 1 = 2T(n-1) + 1
通过这样做,我们将 T(n) 简化为更简单的递归。因此,我们现在可以使用反向替换来求解 T(n)。 为此,我们首先将 T(n-1) 代入递归式的右侧。由于 T(n-1) = 2T(n-2) + 1,我们得到:
T(n) = 2[2T(n-2) + 1] + 1 = 4T(n-2) + 3
接下来,我们可以代入 T(n-2) = 2T(n-3) + 1:
T(n) = 2[2[2T(n-3) + 1] + 1] + 1 = 8T(n-3) + 7
T(n-3) = 2T(n-4) + 1:
T(n) = 2[2[2[2T(n-4) + 1]+ 1] + 1] + 1 = 16T(n-4) + 15
我们可以看到这里开始出现一个模式,所以让我们尝试形成 T(n) 的一般解决方案。看来是这样的:
T(n) = 2kT(n–k) + (2k-1)
对于任何正整数k。我们可以通过简单的归纳证明这个等式成立——为简洁起见,我们将跳过这个过程。
最后,我们可以通过代入 T(0) = 1 找到 k,从而求解 T(n)。
对于 T(0),我们可以看到 n – k = 0。重新排列,我们得到 k = n。现在,将我们的值代入 T(0) 和 k,我们得到:
T(n) = 2nT(0) + (2n-1) = 2n + 2n – 1 = O(2n)
我的问题是为什么它可以用 0 代替 n。在我看来,当 n 达到 1 时程序将终止,因为 T(n-2) 已被 T(n-1) 替换。因此,n 的值为 0 是不可能的。
【问题讨论】:
-
"n 的值为 0 是不可能的。" --> 考虑
fib(0)&fib(2)。在这两种情况下,n==0在某个时候。 -
@chux-ReinstateMonica 在此解决方案中,fib(n-2) 已替换为 fib(n-1)。所以
n==0在这种情况下不会发生在 fib(2) 上 -
可以调用
fib(0)提供的函数。如果你想你也可以替换fib(1),但是返回结果是一样的,所以这个例子没有关系。 -
o o,当
fib(2)被调用时,代码解有fib(n - 1) + fib(n - 2),并递归调用fib(1)和fib(0)。fib(positive_even)最终调用fib(0)。 -
对于这段代码,我认为你不需要任何复杂的分析就能看出它是 Theta(fib(n))。该代码要么返回 1,要么将 fib 的两个返回值相加。由于 fib(n) 的总数必须是第 n 个斐波那契数,因此必须执行 fib(n) 总数
return 1语句,因此执行 (fib(n)-1) 加法(因此 2fib(n) -2 次递归调用)。
标签: algorithm