【题目】
给定整数N,返回斐波那契数列的第N项
【补充1】
给定整数N,代表台阶数,一次可以跨2个或者1个台阶,返回有多少种走法。
【举例】
N=3,可以三次都跨1个台阶;也可以先跨2个台阶,再跨1个;或者先跨1个,再跨2个。所以有三种走法,返回3.
【补充2】
假设农场中成熟的母牛每年只会生1头小母牛,并且永远不会死。第一年农场有1只成熟的母牛,从第二年开始,母牛开始生小母牛。每只小母牛3年之后成熟又可以生小母牛。给定整数N,求出N年后牛的数量。
【举例】
N=6,第1年1头成熟母牛记为a;
第2年a生了新的小母牛,记为b,总牛数为2;
第3年a生了新的小母牛,记为c,总数为3;
第4年a生了新牛d,总数4;
第5年b成熟了,ab分别生了一只,总数为6;
第6年c也成熟了,abc分别生了一只,总数为9,故返回9.
【要求】
对以上所有问题,时间复杂度为O(logN)
【代码】
public static void main(String[] args) {
//原题目
System.out.println(Fibonacci(5));//5
System.out.println(Fibonacci2(5));//5
System.out.println(Fibonacci3(5));//5
}
//返回斐波那契数列的第N项
//方法1:暴力递归,O(2^N)
public static int Fibonacci(int n){
if(n<1){
return -1;
}else if(n==2||n==1){
return 1;
}else{
return Fibonacci(n-1)+Fibonacci(n-2);
}
}
//方法2:依次从左到右求出每一项的值,O(N)
public static int Fibonacci2(int n){
if(n<1){
return -1;
}
if(n==2||n==1){
return 1;
}
int res=1;
int pre=1;
int temp=0;
for(int i=3;i<=n;i++){
temp=res;
res+=pre;
pre=temp;
}
return res;
}
//方法3:矩阵乘法思想,O(logN)
//(F(n),F(n-1))=(1,1)×{{1,1},{1,0}}^(n-2)
public static int Fibonacci3(int n){
if(n<1){
return -1;
}
if(n==2||n==1){
return 1;
}
int[][] base={{1,1},{1,0}};
int[][] res=matrixPower(base,n-2);//状态矩阵的n-2次方
return res[0][0]+res[1][0];
}
//矩阵m的p次方
private static int[][] matrixPower(int[][] m, int p) {
int[][] res=new int[m.length][m[0].length];
//把res设为单位矩阵,相当于整数中的1
for(int i=0;i<res.length;i++){
res[i][i]=1;
}
int[][] tmp=m;
for(;p!=0;p>>=1){
if((p&1)!=0){
res=muliMatrix(res,tmp);
}
tmp=muliMatrix(tmp,tmp);
}
return res;
}
//具体实现两个矩阵相乘
private static int[][] muliMatrix(int[][] m1, int[][] m2) {
int[][] res=new int[m1.length][m2[0].length];
for(int i=0;i<m1.length;i++){
for(int j=0;j<m2[0].length;j++){
for(int k=0;k<m2.length;k++){
res[i][j]+=m1[i][k]*m2[k][j];
}
}
}
return res;
}
本文探讨了如何使用递归和动态规划解决斐波那契数列问题,包括计算斐波那契数列的第N项、解决不同台阶的走法问题以及模拟农场母牛繁殖的问题。要求所有算法的时间复杂度为O(logN)。同时,提供了相关问题的代码实现。
832

被折叠的 条评论
为什么被折叠?



