memoized fibonacci代码中的空间复杂性

时间:2017-01-06 19:32:49

标签: java algorithm big-o space-complexity

void allFib(int n) {
   int[] memo = new int[n + 1];
   for(int i = 0; i < n; i++){
      System.out.println(i + ": "+ fib(i, memo));
   }
}

int fib(int n, int[] memo) {
   if (n <= 0) return 0;
   else if (n == 1) return 1;
   else if (memo[n] > 0) return memo[n];
   memo[n] = fib(n - 1, memo) + fib(n - 2, memo);
   return memo[n];
}

在上面的memoized代码中打印出第一个n个斐波那契数,由于fib方法(memo[n]= fib(n - 1, memo) + fib(n - 2, memo);)中的递归调用,空间复杂度是多少?即使它们看起来像递归调用,它们真正做的只是查找备忘录[n - 1]和备忘录[n - 2],因为它们已经保证已经被计算出来了。但是因为它们是以这种形式并在内存中设置自己的堆栈,那么每个调用是否都有内存占用?如果是这样,是什么?

如果我用memo[n] = memo[n - 1] + memo[n - 2]替换该行,那么THIS行所贡献的空间复杂度将减少到O(1)对吗?

我知道由于大小为n + 1的备忘录数组,整体空间复杂度至少为O(n)。

1 个答案:

答案 0 :(得分:2)

当您计算从最小到最大的顺序Fibonacci数时,即使使用递归调用,额外的空间复杂度也是O(1)

事实上,循环中对fib的每次新调用都会产生两次调用(除了i = 0i = 1,其中没有进行其他调用)。 每次通话都需要恒定的空间。递归的深度以2为界,因此所需的总额外空间是恒定的。

如果您使用求和memo[n] = memo[n - 1] + memo[n - 2]的循环替换它,额外的空间复杂度将保持O(1),因此不会减少。