program-dog

2017年5月14日星期日

时间复杂度为1的求解fibonacci数方法

求Fibonacci数可以用一种通用的方法,得到时间复杂度为O(1)的解,下面是一个例子。这个公式涉及到求n次方问题,如果你自己写了一个n次方的函数,复杂度可能是O(n)或者O(lgn)了,在Java上,源码是用了C的类库,优化后可以认为复杂度为O(1)。

求Fibonacci数

求Fibonacci数可以用一种通用的方法,得到时间复杂度为O(1)的解,下面是一个例子。 已知Fibonacci数表示如下: f(n)={0n=01n=1f(n1)+f(n2)n>1
现在设f(n)=an,则有an=an1+an2,所以: a2a1=0
其解为: a={1521+52
那么f(n)的解包含a的根。则有: f(n)=A(152)n+B(1+52)n
f(0)=0,f(1)=1,则有 {0=A+B1=A(152)+B(1+52)
可以解得: {A=5B=5
所以 f(n)=15((1+52)n(152)n)

在计算机上运行

只能说Fibonacci数是一个非常奇特的数,这是一个可以用无理数表示整数的例子。但是无理数在计算机上运行的时候,运算过程中可能产生小数,导致最终结果不是整数。这个问题很好解决,先证明如下定理: f(n)=[(1+52)n5]+Cn
其中:当a0,使用[a]代表a的整数部分;当n是偶数的时候,令Cn=0,当n是奇数的时候,令Cn=1.我们观察到 p(n)=(152)n5
是一个单调递减的函数,有 0<p(n)<1
所以我们只计算f(n)的整数部分, q(n)=(1+52)n5
根据情况是否补1即可。 所以我们解决了在计算机上运行产生小数的这个问题。

1 条评论 :