Fibonacci数列求解方法总结

来源:互联网 发布:js点击效果 编辑:程序博客网 时间:2024/05/29 03:32

众所周知斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、……是面试中常考的问题,针对Fibonacci数列的求解方法有如下三种:

1、递归方法(Recursive)求解:
递归方法求解Fibonacci数列,可以说是大多数人首次接触到的求解方法,但是也同样存在了很严重的问题,例如:时间复杂度却是成指数倍的增长,因为有很多计算是重复了多次,导致这个方法却是最不可取的求解方法。
时间复杂度:O(2^n)
空间复杂度:O(1)
代码如下(C/C++):

int getFib(int n){    if (0 >= n)    //可具体询问非法输入时返回多少。    {        return 1;    }    return n <= 2 ? 1 : getFib(n-1) + getFib(n-2); }

2、迭代方法(Iterative way)求解:
利用for循环进行迭代,可以解决在求解过程中使用递归的方法导致的重复计算的操作,可有效的提高算法的效率。
时间复杂度:O(n)
空间复杂度:O(n)
代码如下(C/C++):

int getFib(int n) {    if (n <= 0)    {        return 1;    }    int a[N];    a[1] = a[2] = 1;    for (int i = 3; i <= n; ++i)    {        a[i] = a[i-1] + a[i-2];    }    return a[n];}

当然也可以做如下优化,当发现上述代码对于数组a[N]中,仅仅也就使用3个单位,于是可以使用x,y,z等一些变量来代替。更换后可降低空间复杂度。
时间复杂度:O(n)
空间复杂度:O(1)
代码如下(C/C++):

int getFib(int n) {    if (n <= 0)    {        return 1;    }    int x, y, z;    z = x = y = 1;    for (int i = 3; i <= n; ++i)    {        z = x + y;        y = x;        x = z;    }    return z;}

3、矩阵乘法(Matrix multiplication)求解:
由Fibonacci数列的特性可以知道:
(1)当n>1时,可以发现Fib(n)和Fib(n-1)是互质的
(2)若定义一个i为奇数,则f(i)*f(i) = f(i-1)*f(i+1)-1;若i为偶数,则f(i)*f(i)=f(i-1)*f(i+1)-1
(3)f(n)=f(i)*f(n-i-1)+f(i+1)*f(n-i)
f(n)=f(1)*f(n-2)+ f(2)*f(n-1)=f(2)*f(n-3)+ f(3)*f(n-2)=f(3)*f(n-4)+ f(4)*f(n-3)
由方法2可知,若要计算Fib(n),就是要先保存,令a = f(1),b = f(2),然后在进行运算,使a’=b,b’=a+b
可把a,b看做一个向量[a, b],然后乘以矩阵
0 1
1 1
即若要求第100个Fibonacci数,只需要将[1, 1]乘上
0 1
1 1
的100次方,再取出第一项即可。
时间复杂度:O(logn)
空间复杂度:O(1)
代码如下(C/C++):

double exp(int x, int k){    if (k == 0 && x == 0)    {        return 0;    }    if (k == 0)     {        return 1;    }    if (k < 0)     {        return 1.0 / exp(x, -k);    }    double tmp = exp(x, k >> 1);    return k % 2 == 1 ? tmp * tmp * x : tmp * tmp;}
1 0
原创粉丝点击