题目背景就不再多说了,直奔主题。三个方法,递归,迭代与快速幂。
递归方法
public int fib(int n) {
if (n == 1 || n == 2) return 1;
else return (fib(n-1)+fib(n-2));
}
时间复杂度: O ( 2 n ) O(2^n) O(2n),并且会爆栈
迭代方法
显然我们其实只需要前两个状态量,因此直接保存前两个
public int fib(int n) {
if (n == 0) return 0;
if (n == 2 || n == 1) return 1;
int x = 1;
int y = 1;
int z = 1;
for(int i = 3; i<=n;i++){
z = x+y;
x = y;
y = z;
}
return z;
}
快速幂
核心就是
class Solution {
public int fib(int n) {
if (n<2)return n;
int[][] q = {{1,1},{1,0}};
int[][] res = pow(q, n-1);
return res[0][0];
}
// 矩阵快速幂
public int[][] pow(int[][] q, int a){
int[][] ans = {{1,0},{0,1}}; // 这里一定要传入初始值的
while (a>0){
if ((a&1) == 1) ans = multipy(ans, q);
a >>= 1;
q = multipy(q, q);
}
return ans;
}
// 矩阵乘法
public int[][] multipy(int[][] a, int[][] b){
int[][] ans = new int[2][2];
for (int i = 0; i<2;i++){
for (int j = 0; j<2;j++){
ans[i][j] = a[i][0]*b[0][j]+a[i][1]*b[1][j];
}
}
return ans;
}
}
这样的时间复杂度是可以近似的认为是是 O ( l o g n ) O(logn) O(logn)的