这个斐波纳契序列算法的MEMORY复杂度是多少?

时间:2015-03-16 18:28:58

标签: java big-o

我最近做过技术访谈,并被问到我在白板上编写的以下算法的内存复杂性。更具体地说,如果我没记错的话,他指的是"堆空间":

public int[] fib = new int[1000];
public int fibonacci(int i) {
    if (i == 0) return 0;
    if (i == 1) return 1;
    if (fib[i] != 0) return fib[i];
    fib[i] = fibonacci(i - 1) + fibonacci(i - 2);
    return fib[i];
}

因为他说"堆积空间",听起来他给了我一个线索,他希望我给出以下代码行的复杂性:

public int[] fib = new int[1000];

我想我记得在学校里学习Java中的new与C中的malloc类似,malloc在堆中分配存储。假设我的记忆正确地为我服务,现在回到我的问题:这是什么内存复杂性?我应该说O(1000)吗?上)?还有别的吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

我认为您的面试官想知道您对所编写代码的后果有多了解。非尾调用递归代码的常见潜在内存问题是每个递归调用占用堆栈帧,在完成调用(包括其所有递归子调用)之前,不能对其进行垃圾收集。堆栈帧是从堆中分配的,因此递归可以耗尽堆。

如果没有保存和检索已经计算的斐波那契数的记忆快捷方式,则内存复杂度将为O(n 2 ):计算第n个斐波那契数将创建一个与之成比例的堆栈帧的递归树n的平方,因为它重新计算了树的不同分支的相同数字。

但是发布的代码不应该不止一次计算任何一个斐波纳契数,并且堆栈帧的总数不会以相同的方式爆炸,对于最坏的情况,它将被保持为O(n) ,数组最初是空的。一旦填充了数组,它就是O(1),因为在那时它相当于单个数组查找。

答案 1 :(得分:0)

O(n)对我来说似乎是对的。你不会在O表示法中包含常量(如O(1000))。

顺便说一句,这是我对递归函数的问题,它的开放式内存复杂性。除非我能对输入大小设置限制,否则我不能使用这种递归函数。