剑指offer-斐波那契数列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zwzsdy/article/details/79948053

题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。
n<=39

这道题目描述简单,如果使用暴力法也是能够计算出结果的,但是既然是算法,我们必然要考虑时间复杂度。

我们可以有这样一个递推公式:

[Fib(n+1)Fib(n)]=[1110]
[Fib(n)Fib(n1)]

然后,进行多次递推,实际上就是

[1110]
求它的n次幂。
对于求幂,存在一个算法——快速幂,时间复杂度为logn,实现也非常简单:

ll f(ll a,ll b,ll n){
  int t,y;
  t=1; y=a;
  while (b!=0){
    if (b&1==1) t=t*y%n;
    y=y*y%n; b=b>>1;
  }
  return t;
}

那么,这道题其实就是计算矩阵的n次幂,编写一个函数来计算函数乘法即可。

public class Solution {
        class arr{
        public int [][]s=new int[2][2];
    }
    public int Fibonacci(int n) {
        if(n<1) {return 0;}
        if(n==1||n==2) {
            return 1;
        }
        n=n-2;
        arr y=new arr();
        y.s[0][0]=1;
        y.s[0][1]=1;
        y.s[1][0]=1;
        y.s[1][1]=0;
        //单位矩阵
        arr re=new arr();
        re.s[0][0]=1;
        re.s[0][1]=0;
        re.s[1][0]=0;
        re.s[1][1]=1;
        while(n!=0) {//快速幂
            if((n&1)==1) {//奇数
                re=Muti(re, y);
            }
            y=Muti(y, y);
            n>>=1;
        }
        return (re.s[0][0]+re.s[0][1]);
    }
    private arr Muti(arr a1,arr a2) {//计算矩阵乘积
        arr temp=new arr();
        int te=0;
        for(int i=0;i<2;i++) {
            for(int j=0;j<2;j++) {
                for(int k=0;k<2;k++) {
                    te+=a1.s[i][k]*a2.s[k][j];
                }
                temp.s[i][j]=te;
                te=0;
            }
        }
        return temp;

    }
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页