package day02;
public class 斐波那契数列 {
/** 可以使用矩阵幂进行计算,时间复杂度可以降低到O(log(n))
*/
/**
* 思路:
* [F(n), F(n-1)] = [F(n-1), F(n-2)] * [[1, 1], [1, 0]]
* = [F(n-2), F(n-3)] * [[1, 1], [1, 0]]^2
* = [F(1), F(0)] * [[1, 1], [1, 0]]^(n-1)
* F(1)=1,F(0)=0,所以现在要求的是矩阵[[1, 1], [1, 0]]的(n-1)次幂
*/
public static int Fibonacci(int n) {
if(n == 0)
return 0;
if(n == 1)
return 1;
int[][] matrix = {{1, 1}, {1, 0}};
int[][] powOfMatrix = PowOfMatrix(matrix, n-1);
int res = powOfMatrix[0][0];
return res;
}
//求matrix的k次幂,根据:matrix^k = (matrix^(k/2) * matrix^(k/2)) * matrix^(k%2)
public static int[][] PowOfMatrix(int[][] matrix, int k){
if(k == 0) {
//返回单位矩阵
int[][] res = new int[2][2];
res[0][0] = res[1][1] = 1;
res[0][1] = res[1][0] = 0;
return res;
}
if(k == 1)
return matrix;
int[][] tmp1 = matrixByMatrix(PowOfMatrix(matrix, k/2), PowOfMatrix(matrix, k/2));
int[][] tmp2 = PowOfMatrix(matrix, k%2);
return matrixByMatrix(tmp1, tmp2);
}
public static int[][] matrixByMatrix(int[][] matrix1, int[][] matrix2){
//这里专门计算两个2*2的矩阵乘积
int[][] res = new int[2][2];
res[0][0] = matrix1[0][0]*matrix2[0][0] + matrix1[0][1]*matrix2[1][0];
res[0][1] = matrix1[0][0]*matrix2[0][1] + matrix1[0][1]*matrix2[1][1];
res[1][0] = matrix1[1][0]*matrix2[0][0] + matrix1[1][1]*matrix2[1][0];
res[1][1] = matrix1[1][0]*matrix2[1][0] + matrix1[1][1]*matrix2[1][1];
return res;
}
public static void main(String[] args) {
for(int i=0;i<20;i++) {
System.out.println(Fibonacci(i));
}
}
}