斐波那契数列:最直观的想法是,由于fib(x)=fib(x-1)+fib(x-2),其中x>=3,当x=1或者2时,fib(x)=1,那么我们不妨令a=1,b=1,c=1,其中循环从3开始直到n,不断交替变换,使得c=a+b,a=b,b=c,如此最后c即是我们想要的结果。
int Fibonacci(int n) { int a=1,b=1,c=1; for(int i=3;i<=n;i++) { c=a+b; a=b; b=c; } return c; }
idea:由于题目直接给出了递推公式,那么我们也可以使用递归来做。
int Fibonacci(int n) { int f; if((n==1)||(n==2)) return 1; if(n>=3) f=Fibonacci(n-1)+Fibonacci(n-2); return f; }
idea:既然有递推公式,也可以使用递归来做,那么必然可以使用动态规划来做,因为递归是将大问题分解为小问题,而动态规划是将小问题推导为大问题。
int Fibonacci(int n) { vector<int> dp(n); dp[0]=1; dp[1]=1; for(int i=2;i<n;i++) dp[i]=dp[i-1]+dp[i-2]; return dp[n-1]; }
数学:由于有fib(n)=fib(n-1)+fib(n-2),然后又有fib(n-1)=fib(n-2)+fib(n-3)……,该题本质上是求fib(n)对应计算了多少次的fib(1)和多少次的fib(0),那么我们可以转换为如下公式,最后结果为矩阵的n-1次方的第一行第一列的数。
typedef struct Matrix{ int a,b,c,d; //2*2矩阵 }Matrix; Matrix Matrix_Multiply(Matrix &x,Matrix &y) //矩阵乘法 { Matrix z; z.a=x.a*y.a+x.b*y.c; z.b=x.a*y.b+x.b*y.d; z.c=x.c*y.a+x.d*y.c; z.d=x.c*y.b+x.d*y.d; return z; } Matrix Matrix_Quick_Pow(Matrix &x,int n) //矩阵快速幂 { Matrix ans={1,0,0,1}; //初始化为单位矩阵 while(n>0) { if(n&1) //最低位为1 ans=Matrix_Multiply(ans, x); //将x乘入结果 x=Matrix_Multiply(x, x); //将x乘以x为下次做准备 n>>=1; //右移一位 } return ans; } class Solution { public: int Fibonacci(int n) { //最后结果为矩阵的n-1次方的第一行第一列的数 Matrix x={1,1,1,0}; //基础矩阵 Matrix ans=Matrix_Quick_Pow(x, n-1); return ans.a; } };