问题描述
我正在阅读有关fib解决方案的这篇文章(非常有帮助):https://medium.com/@johanna.fulghum/write-the-fibonacci-sequence-in-every-computational-complexity-9adf5ef12775
但是她的上次解决时间和空间复杂度是否有错字?
function fib(n,a = 0,b = 1){
if (n > 0) {
return fib(n - 1,b,a + b)
}
return a
}
她说:“这种尾部递归解是常数O(n)时间和常数O(n)空间复杂度。这是无法击败的。她的意思是O(1)对吗?由于O(n)是线性的。另外,我看到它的O(1)空间如何,但是有人可以解释为什么它是O(1)时间吗?对我来说好像是O(n)时间
解决方法
是的,这是一个错字(或编辑错误),并且空间复杂度还取决于编译器优化的确是恒定的O(1)
。
此代码的复杂度为Theta(n)
时间,空间复杂度可以为Theta(n)
或Theta(1)
,具体取决于编译器是否优化了尾递归循环。如果它确实优化了尾递归,那么代码基本上与她的解决方案3等效。
function fibs(n){
let [a,b] = [0,1]
while (n > 0){
[a,b] = [b,a + b]
n -= 1
}
return a
}
我也对This can’t be beat
的声明感到担忧。
实际上,斐波那契有一个closed form formula,可以使用O(logn)
来计算,假设乘法是在恒定时间内完成的。 1
(1)如果该假设不成立,并且您实际上还关心算术运算的复杂性,那么答案就变得复杂了。基本上,这意味着您的复杂性取决于输出的大小,输出的大小也呈指数增长。由于这成倍增长。由于它呈指数增长,因此需要O(log(result))
位来表示它,然后得到线性时间的下限,因为输出的大小本身在n
中是线性的。