代码之家  ›  专栏  ›  技术社区  ›  BROCK

如果删除“第3行”,fib(n)需要多少额外的函数调用?

  •  10
  • BROCK  · 技术社区  · 16 年前

    我刚在面试中得到这个问题,不知道如何计算答案。

    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);
    }
    
    3 回复  |  直到 16 年前
        1
  •  7
  •   jpalecek    16 年前

    这很容易计算。旧代码:

    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开始的斐波那契数列。也可以为它计算一个封闭形式的表达式。

        2
  •  4
  •   Pratik Deoghare    16 年前

    还有斐波那契

    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;
        }
    }
    

    注:我认为这是一个常数,但。。。

        3
  •  -1
  •   Roman    16 年前

    假设没有第三条直线,计算f(3):

    f(3) = f(2) + f(1)
    f(1) = 1
    f(2) = f(1) + f(0)
    f(0) = 0
    f(1) = 1
    

    该算法的复杂度(没有第三行)是 O(2^n) . 当您添加第3行时,其中包含用于以下情况的显式解决方案: n = 2 复杂性变得 O(2^(n-1)) (1/2) * O(2^n) kO(2^n) 其中k=0.5。如果在n=3的情况下加上显式解,则得到k=0.25,依此类推。当你添加 p 显式解决方案的复杂性将是:

        1
    O (--- * 2^n)
       2^p 
    

    p = n - 1 以及它们各自的算法 n 步骤和舒适性将 2*O(n)