方法1:
利用递归方法,但是递归看似简单但是无法处理较大的项数,时间复杂度为o(2^n)。
public class fib_递归 {
/**
* @param args
*/
public static void main(String[] args) {
int n=10;
System.out.println(fib(n));
}
private static int fib(int n) {
if(n==1 || n==2){
return 1;
}
return fib(n-1)+fib(n-2);
}
}
方法2:
利用f(n)=f(n-1)+f(n-2),这一递推方程,不断向后顺序计算即可,时间复杂度为o(n)。
public class fib_dp {
/**
* @param args
*/
public static void main(String[] args) {
int n=5;
System.out.println(fib(n));
}
private static int fib(int n) {
if(n==1 || n==2){
return 1;
}
int sec=1;//第二项
int fir=1;//第一项
int temp=0;//临时项
for (int i = 3; i <= n; i++) {
temp=sec;
sec=fir+sec;
fir=temp;
}
return sec;
}
}
方法3:
f(n)=f(n-1)+f(n-2) 是二阶递推式,我们可以将它表示成二阶矩阵的形式
(f(n),f(n-1))=(f(n-1),f(n-2))*(a,b|c,d) (注:(a,b|c,d)是一个二阶矩阵,第一行为(a,b),第二行为(c,d))
因为f(1)=1,f(2)=1,f(3)=2,f(4)=3,带入上述矩阵方程中可得a=1 , b=1 , c=1 , d=0。
所以(f(n),f(n-1))=(f(n-1),f(n-2))*(1,1|1,0)
要想计算f(n)
我们可以观察一下递推式:
(f(3),f(2))=(f(2),f(1))*(1,1|1,0)
(f(4),f(3))=(f(3),f(2))*(1,1|1,0)
.......
(f(n),f(n-1))=(f(n-1),f(n-2))*(1,1|1,0)
将上述等式左右两边相乘
得(f(n),f(n-1)) = (1,1) * [(1,1|1,0)^n-2]
所以求第n项值的问题就转化为求矩阵幂的问题
public class fib快速幂 {
/**
* @param args
*/
public static void main(String[] args) {
int n=20;
System.out.println(fib(n));
}
private static int fib(int n) {
if(n<1)return 0;
if(n==1 || n==2){
return 1;
}
int base[][]={{1,1},{1,0}};
int res[][]=matrixp(base,n-2);
return res[0][0]+res[0][1];
}
private static int[][] matrixp(int[][] m, int n) {
int res[][]=new int[m.length][m[0].length];
for (int i = 0; i < res.length; i++) {
res[i][i]=1;
}
int temp[][]=m;
for (; n!=0; n>>=1) {
if((n&1)!=0){
res=muli(res,temp);
}
temp=muli(temp,temp);
}
return res;
}
private static int[][] muli(int[][] m1, int[][] m2) {
int r[][]=new int[m1.length][m2[0].length];
for (int i = 0; i < r.length; i++) {
for (int j = 0; j < r[0].length; j++) {
for (int k = 0; k < m2.length; k++) {
r[i][j]+=m1[i][k]*m2[k][j];
}
}
}
return r;
}
}