我正在学习java复发,但我坚持以下问题。
void f(int n) {
if (n<=1) return;
f(n/2);
System.out.writeln("still continuing...");
f(n/2);
f(n/2);
}
我有两个问题。
如果我们说T(n)是程序打印的行数而n是输入,那么T(n)的递推公式是什么?
如何在不使用主定理的情况下解决问题1的复发?
欢呼声
答案 0 :(得分:3)
让我们从T(n)的值的公式开始。我们知道以下内容:
因此,我们可以得到以下重复:
请注意,我在这里使用“+ 1”术语而不是“+ O(1)”术语。这在数学上是不确定的,但是因为我们正在寻找用big-O表示法表达的最终结果,所以这不会是一个太大的问题。
现在,我们将如何解决此问题?一种选择是为n插入一些任意值,看看会发生什么。我们从(假设n> 1)开始
T(n)≤3T(n / 2)+ 1
现在,让我们考虑一下对T(n / 2)的调用。如果n / 2> 1,然后我们得到那个
T(n)≤3T(n / 2)+ 1
≤3(3T(n / 4)+ 1)+ 1
= 9T(n / 4)+ 3 + 1
现在,让我们扩大这个收益:
T(n)≤9T(n / 4)+ 3 + 1
≤9(3T(n / 8)+ 3)+ 3 + 1
= 27T(n / 8)+ 9 + 3 + 1
此时,我们可以看到一种模式出现。在迭代迭代后,我们完成了总工作
T(n)= 3 i T(n / 2 i )+ sum(i = 0到i - 1)3 i
当n / 2 i ≤1时,该过程终止,这发生在i≈lln时。如果我们插入lg n,我们得到
T(n)≤3 lg n T(1)+ sum(i = 0到i - 1)3 i )
≤3 lg n + sum(i = 0到i - 1)3 lg n
现在,3 lg n = 3 (log3 n / log3 2) = 3 log3 n 1 / log3 2 < / sup> = n 1 / log3 2 ,所以整个事情都是
T(n)≤n 1 / log3 2 + sum(i = 0到(lg n)-1)3 i
使用几何级数之和的公式,这最后一项是(3 lg n -1)/ 2,最终扩展到O(n 1 / log3 2 < / sup>),总的来说这个表达式是O(n 1 / log 3 2 )。
但这个公式真的很难看。我们可以简化它吗?好吧,我们确实有这个:
1 / log 3 2 = log 2 3
这使我们的运行时间为O(n lg 3 ),大约为O(n 1.58 )。
希望这有帮助!
答案 1 :(得分:0)
T(n) = 3* T(n/2)+ O(1)
正如定理所示,答案应为O(n ^(lg 3))。
有关详细信息,请参阅Cormen等人的算法简介,请参阅第4章。 求解复指数方程非常复杂。但通常这种方法是先猜测,然后用替换证明。