面试题10:斐波那契数列
题目一:写一个函数,输入n,求斐波那契数列的第n项。
方法1:递归求解
package jianZhiOffer;
import java.util.Scanner;
/*
* 面试题10:斐波那契数列
* 题目一:写一个函数,输入n,求斐波那契数列的第n项。
*/
public class O10Fibonacci {
public static int fib1(int n) {
int result[] = {0,1};
if(n<2) {
return result[n];
}
int fibNone = 1;
int fibNtwo = 0;
int fibN = 0;
for(int i=2;i<=n;i++) {
fibN = fibNone +fibNtwo;
fibNtwo = fibNone;
fibNone = fibN;
}
return fibN;
}
方法2:时间复杂度O(logn)的求解
斐波那契数列的定义:
用递推地方式的fan得方式得出如下结论:
所以要求第n项的值变成了求矩阵与矩阵的相乘,还有矩阵的n次幂的求法。
求整数的n次幂的O(logn)复杂度的求法:
整数的n次幂可以划分为如上的两部分来计算,,对于无论是奇数还是偶数,只要指数右移一位就可以,当是奇数时,最后再乘个a即可。
p>>1:
p右移一位相当于p除以2,,p/2
public static int fib2(int n) {
if(n<1)
return 0;
if(n==1 || n==2)
return 1;
int[][] base = {{1,1},{1,0}};
int[][] res = matrixPower(base, n-2);//斐波那契数列((F(n), F(n-1)为(1,1)
//与{{1,1},{1,0}}的n-2次幂的乘积
return res[0][0]+res[1][0];
}
public static int[][] matrixPower(int[][] m, int p){//求矩阵的p次幂的方法,与求
//整数的次幂的道理一样
if(p==0)
return null;
if(p==1)
return m;
int[][] res = matrixPower(m,p>>1);
res = muliMatrix(res,res);
if((p&1)==1) {
res=muliMatrix(res,m);
}
return res;
}
public static int[][] muliMatrix(int[][] m1, int[][] m2){
//求两个矩阵相乘得到一个新的矩阵
int[][] res = new int[m1.length][m2[0].length];
for(int i=0;i<m1.length;i++) {//i为m1的行
for(int j=0;j<m2[0].length;j++) {//j为m2的列
for(int k=0;k<m2.length;k++) {
res[i][j] += m1[i][k]*m2[k][j];
}
}
}
return res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int fn1 = fib1(n);
int fn2 = fib2(n);
System.out.println("斐波那契数列的第n项为"+fn1);
}