所以,我们看到很多斐波纳契问题。我个人非常讨厌他们。很多。不止一切。我认为如果我们可以让任何人都不可能再次将其用作面试问题,那就太好了。让我们看看有多接近O(1)我们可以得到斐波那契。
这是我的开始,几乎来自维基百科,当然还有足够的空间。重要的是,这个解决方案将引爆任何特别大的fib,它包含一个相对天真的power函数使用,如果你的库不好,它会把它放在最坏的O(log(n))。我怀疑我们可以摆脱电源功能,或至少专攻它。有人帮忙吗?除了使用查找表的有限*解决方案之外,是否存在真正的O(1)解决方案?
#include <iostream>
#include <math.h>
using namespace std; // would never normally do this.
int main()
{
int target = 10;
cin >> target;
// should be close enough for anything that won't make us explode anyway.
float mangle = 2.23607610;
float manglemore = mangle;
++manglemore; manglemore = manglemore / 2;
manglemore = pow(manglemore, target);
manglemore = manglemore/mangle;
manglemore += .5;
cout << floor(manglemore);
}
*我知道,我知道,这足以满足斐波那契的任何零实际用途。
答案 0 :(得分:46)
这是Fibonacci序列项的近O(1)
解。不可否认,O(log n)
取决于系统Math.pow()实现,但如果您的采访者正在寻找,那么Fibonacci没有可见的循环。 ceil()
归因于返回.9重复的较大值的舍入精度。
JS中的示例:
function fib (n) {
var A=(1+Math.sqrt(5))/2,
B=(1-Math.sqrt(5))/2,
fib = (Math.pow(A,n) - Math.pow(B,n)) / Math.sqrt(5);
return Math.ceil(fib);
}
答案 1 :(得分:18)
给定任意大输入,简单地读入n需要O(log n),因此在这个意义上没有恒定时间算法是可能的。因此,使用封闭形式的解决方案,或预先计算您关心的值,以获得合理的性能。
编辑:在评论中指出它实际上更糟糕,因为斐波纳契是O(phi^n)
打印斐波那契的结果是O(log (phi^n))
{{ 1}}!
答案 2 :(得分:15)
以下答案在O(1)中执行,但我不确定它是否符合你的问题。它被称为Template Meta-Programming。
#include <iostream>
using namespace std;
template <int N>
class Fibonacci
{
public:
enum {
value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value
};
};
template <>
class Fibonacci<0>
{
public:
enum {
value = 0
};
};
template <>
class Fibonacci<1>
{
public:
enum {
value = 1
};
};
int main()
{
cout << Fibonacci<50>::value << endl;
return 0;
}
答案 3 :(得分:5)
在编程:算法的推导中,Anne Kaldewaij扩展了the linear algebra solution以获得(从该书中使用的编程语言翻译和重构):
template <typename Int_t> Int_t fib(Int_t n)
{
Int_t a = 0, b = 1, x = 0, y 1, t0, t1;
while (n != 0) {
switch(n % 2) {
case 1:
t0 = a * x + b * y;
t1 = b * x + a * y + b * y;
x = t0;
y = t1;
--n;
continue;
default:
t0 = a * a + b * b;
t1 = 2 * a * b + b * b;
a = t0;
b = t1;
n /= 2;
continue;
}
}
return x;
}
这具有O(log n)复杂性。当然,这不是常数,但我认为值得添加到讨论中,特别是考虑到它只使用相对快速的整数运算而且不可能舍入误差。
答案 4 :(得分:1)
是。预先计算值,并存储在数组中, 然后使用N进行查找。
答案 5 :(得分:1)
选择要处理的最大值。对于任何更大的值,请引发错误。对于任何小于该值的值,只需将答案存储在该较小的值,并继续运行“最大”值的计算,并返回存储的值。
毕竟,O(1)
具体意味着“常数”,而非“快速”。使用此方法,所有计算都将花费相同的时间。
答案 6 :(得分:0)
O(1)时空中的斐波那契数(Python实现):
PHI = (1 + sqrt(5)) / 2
def fib(n: int):
return int(PHI ** n / sqrt(5) + 0.5)