C ++:fibonacci的三种递归实现时间/空间复杂度是多少?

问题描述

我编码了斐波那契数列的三个版本,但我不确定它们的时间/空间复杂度(以及原因):

变体1:头部递归

 int fibonacci_h(int n) {
  if (n == 1 || n == 2) {
    return 1;
  }
  return fibonacci_h(n - 1) + fibonacci_h(n - 2);
}

变体2:尾递归

int fibonacci_t(int n,int s_last = 0,int last = 1) {
  if (n == 1) {
    return last;
  }
  return fibonacci_t(n - 1,last,s_last + last);
}

变体3:具有缓存的头部递归

int fibonacci_hash(int n,unordered_map<int,int>* fib_hash = new unordered_map<int,int>{{1,1},{2,1}}) { 
  if((*fib_hash).find(n)!=((*fib_hash).end())){
    return  (*fib_hash)[n];
  }
  int result = fibonacci_hash(n - 1,fib_hash) + fibonacci_hash(n - 2,fib_hash);
  (*fib_hash)[n] = result;
  return result;
} 

用法

int main() {
  int n = 10;
  cout << fibonacci_h(n) << endl;
  cout << fibonacci_t(n) << endl;
  cout << fibonacci_hash(n) << endl;
} // Output: 55

非常感谢!

解决方法

一个进行简单递归的人(您称其为头递归)是指数O(2 ^ n)。其他两个是O(n)。备忘一和尾递归一都是O(n)空间。前者的哈希表大小为O(n),后者的调用堆栈深度为O(n),而没有尾递归优化。通过尾部递归优化,该代码基本上可以编译为O(n)时间和O(1)空间的迭代版本。

,

我也提到过this answer-您的“头部”版本的时间复杂度为Θ(((1 + sqrt(5))/ 2)^ n)〜=Θ(1.618 ^ n)。这与golden ratio有关。

enter image description here

渐近地,(a + b)/ a = a / b,即1 + b / a = a / b; (1 + sqrt(5))/ 2是该方程式的解。显然,这也是自然界中的海螺特征。

“头部”版本的空间复杂度为Θ(n),因为这由递归的最大 depth 决定(每个级别的Deep都会添加另一个恒定数量的局部变量和堆栈信息)

我忽略了成为单个整数的log(n)位。也就是说,如果您想超级学究,实际上应该将所有内容乘以log(n)时间。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...