斐波那契数列第n项的三种求法

方法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)

        我们可以观察一下递推式:

扫描二维码关注公众号,回复: 4778344 查看本文章

                                             (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;
	}

}


猜你喜欢

转载自blog.csdn.net/qq_39020387/article/details/79757413