我刚接受采访时提出这个问题,不知道如何计算答案 如果删除“LINE 3”,fib(n)需要多少额外的函数调用?答案应该是n。
int fib(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
if(n == 2) return 1; //LINE 3 HERE <---
return fib(n - 1) + fib(n - 2);
}
答案 0 :(得分:7)
可以很容易地计算出来。旧代码:
TO(0)=TO(1)=TO(2)=1
TO(n)=TO(n-1)+TO(n+2)+1
新代码:
TN(0)=TN(1)=1
TN(n)=TN(n-1)+TN(n-2)+1
差异只是通过减去这两个来计算:
D(0)=D(1)=0
D(2)=3-1=2
D(n)=TN(n)-TO(n)=TN(n-1)+TN(n-2)+1-(TO(n-1)+TO(n+2)+1)
=(TN(n-1)-TO(n-1))+(TN(n-2)-TN(n-2))+(1-1)
=D(n-1)+D(n-2)
这意味着差异是从0,0,2开始的斐波那契序列。也可以为它计算闭合表格式。
答案 1 :(得分:4)
所需的额外呼叫数量是还有Fibonacci 类型的序列。
0 0 2 2 4 6 10 16 26 42 68 110 178 288 466
#include<iostream>
using namespace std;
int a = 0;
int b = 0;
int fib(int n) {
a++;
if(n == 0) return 0;
if(n == 1) return 1;
if(n == 2) return 1; //LINE 3 HERE <---
return fib(n - 1) + fib(n - 2);
}
int fib1(int n) {
b++;
if(n == 0) return 0;
if(n == 1) return 1;
return fib1(n - 1) + fib1(n - 2);
}
int main(int argc, char* argv[])
{
for(int i =0 ;i<15;i++)
{
fib(i);
fib1(i);
cout<<b-a<<" ";
b = a = 0;
}
}
注意:我认为它会有些不变但是......
答案 2 :(得分:-1)
我们假设没有第3行并计算f(3):
f(3) = f(2) + f(1)
f(1) = 1
f(2) = f(1) + f(0)
f(0) = 0
f(1) = 1
现在需要3次调用来计算f(2)。它有一个第3行然后这将在1个电话中完成。
此算法(没有第3行)的复杂性为O(2^n)
。当您添加第3行时,其中包含n = 2
时案例的显式解决方案,复杂性变为O(2^(n-1))
等于(1/2) * O(2^n)
= kO(2^n)
,其中koefficient k = 0.5。如果为n = 3的情况添加显式解,那么得到k = 0.25,依此类推。当您添加p
显式解决方案时,复杂性将是:
1
O (--- * 2^n)
2^p
这意味着,如果您要计算从1到n的n的答案,并且如果您将保存所有计算出的解决方案,那么您将获得p = n - 1
和每个n
步骤的算法复杂性为2*O(n)
。