更新于2020/7/2
对于Fibonacci数列有以下地推公式:
F
n
=
F
n
−
1
+
F
n
−
2
F_n = F_{n-1}+F_{n-2}
Fn=Fn−1+Fn−2
按照这个公式设计算法,时间复杂度为 O ( n ) O(n) O(n)
对于Fibonacci数列又有以下的定理:
[
F
n
+
1
F
n
F
n
F
n
−
1
]
=
[
1
1
1
0
]
n
\begin{bmatrix} F_{n+1} & F_{n} \\ F_{n} & F_{n-1} \end{bmatrix} = {\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}}^n
[Fn+1FnFnFn−1]=[1110]n
然后依据上面的这个定理求
n
n
n次幂可以将时间复杂度降至
log
n
\log n
logn,但是这个在我实现之后发现,除非n非常大,否则使用矩阵求幂的速度反而不如直接使用递推公式的快,因为每求一次幂,都需要进行
至少8次乘法和四次加法,而直接使用递推公式只有一次加法。
Fibonacci数列—矩阵公式
/**
* @author: modev
* @date: 2020/7/2 13:58
* @description: 使用公式,时间复杂度降至对数级
* @param n 输入n
* @return int 返回第n个数的值
* */
public int fib(int n) {
if (n == 0) { return 0; }
int[][] matrix = { {1, 1}, {1, 0}};
int[][] res = helper(n-1, matrix);
return res[0][0];
}
/**
* @author: modev
* @date: 2020/7/2 14:43
* @description: 求矩阵的n次幂
* @param n 输入n
* @param matrix 矩阵
* @return int[][] n次幂的结果
* */
public int[][] helper(int n, int[][] matrix) {
//n=1.直接返回结果,无需再进行分割
if (n == 1) { return matrix; }
int[][] helf;
//n为偶数 分割成两个n/2,然后相乘
if (n % 2 == 0) {
helf = helper(n/2, matrix);
int a = helf[0][0]*helf[0][0] + helf[0][1]*helf[1][0];
int b = helf[0][0]*helf[0][1] + helf[0][1]*helf[1][1];
int c = helf[0][0]*helf[1][0] + helf[1][0]*helf[1][1];
int d = helf[0][1]*helf[1][0] + helf[1][1]*helf[1][1];
return new int[][] {{a, b}, {c, d}};
}else { //n为奇数,分割成两个(n-1)/2相乘后再乘一个matrix
helf = helper((n-1)/2, matrix);
int a = helf[0][0]*helf[0][0] + helf[0][1]*helf[1][0];
int b = helf[0][0]*helf[0][1] + helf[0][1]*helf[1][1];
int c = helf[0][0]*helf[1][0] + helf[1][0]*helf[1][1];
int d = helf[0][1]*helf[1][0] + helf[1][1]*helf[1][1];
return new int[][] {{a + b, a}, {c + d, c}};
}
}
Fibonacci数列—迭代
/**
* @author: modev
* @date: 2020/7/2 13:51
* @description: 求斐波那契数列,连续迭代得到结果
* @version: 1.0
* @param n 输入n
* @return int 返回第n个数的值
* */
public int fib1(int n) {
if (n == 0) { return 0; }
if (n == 1) { return 1; }
int[] counts = new int[n+1];
counts[0] = 0;
counts[1] = 1;
for (int i = 2; i <= n; i++) {
counts[i] = (counts[i-1] + counts[i-2]);
}
return counts[n];
}
Fibonacci数列—递归
//Fibonacci数列的递归实现算法
//F(1)=1、F(2)=2、F(n)=F(n-1)+F(n-2)
public int fibonacci( int n ){
//出现输入小于等于0的时候直接返回0
if ( n <= 0 ){
return 0;
}else if ( n == 1 ){
return 1;
}else if ( n == 2 ){
return 2;
}else
return fibonacci(n-1) + fibonacci(n-2);
}
n的阶乘递归算法
//n的阶乘的递归实现算法
public int factorial( int n ) {
//出现输入小于等于1的时候输出为1
if ( n <= 1 )
return 1;
else
return n*factorial(n-1);
}