求解方法
1. 递归法
可读性好,但效率低,时间复杂度为O(n*n)
2. 窗口滑动法
时间复杂度为O(n),
public int fibonacci(int n){
int a = 0;
int b = 1;
for (int i = 0; i < n - 1; i++) {
int c = a + b;
a = b;
b = c;
}
return a;
}
3. 矩阵幂乘法
时间复杂度O(log2n)
推导过程如下:
java 实现如下:
public int getNthNumber(int n) {
//前两项判断
int flag = n-1;
if(flag==0 ){
return 0;
}else if (flag==1) {
return 1;
}
//n>=2 处理
long[][] base=new long[2][2];
base[0][0]=1;
base[0][1]=1;
base[1][0]=1;
base[1][1]=0;
//求矩阵matrix的(n-1)次方;
long[][] ret={{1,0},{0,1}};//初始化为单位矩阵E
int exp=flag-1;
long[][] tmp;
while (exp>0){
//奇数次幂
if((exp&1)>0){
//ret*base
tmp=new long[2][2];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++){
tmp[i][j]+=ret[i][k]*base[k][j];//数组相乘
}
}
}
ret=Arrays.copyOf(tmp,tmp.length);//ret改值
}
//偶数次幂
//base*base
tmp=new long[2][2];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++){
tmp[i][j]+=base[i][k]*base[k][j];//注意这里的code
}
}
}
base=Arrays.copyOf(tmp,tmp.length);//ret改值
//exp右移一位
exp=exp>>1;
}
//最后:ret第一行和两行一列矩阵[1,0]进行相乘,得到一个整数,即为所求.所以可以简化为将ret第一行数字进行相加即为所求
return (int)(ret[0][0]);
}