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)。
答案 0 :(得分:2)
当您计算从最小到最大的顺序Fibonacci数时,即使使用递归调用,额外的空间复杂度也是O(1)
。
事实上,循环中对fib
的每次新调用都会产生两次调用(除了i = 0
和i = 1
,其中没有进行其他调用)。
每次通话都需要恒定的空间。递归的深度以2为界,因此所需的总额外空间是恒定的。
如果您使用求和memo[n] = memo[n - 1] + memo[n - 2]
的循环替换它,额外的空间复杂度将保持O(1)
,因此不会减少。