Java实现斐波那契数列(递归、遍历、矩阵)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lin_wj1995/article/details/82872644

什么是斐波那契数列

其实很简单,可以理解为:
F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
比如这样一个数列:1、1、2、3、5、8、13、21、34、……
有兴趣可以看百度百科


下面我们就来实现,给定一个n,求f(n)的值

递归解法

递归方法其实是对方法定义完美的一对一实现,但是时间复杂度为O(2的n次方)
代码如下:

    /**
     * 采用递归的方式实现的
     * 时间复杂度为O(2的N次方)
     * @param n
     * @return
     */
    public static int f1(int n){
        if (n == 0){
            return 0;
        }
        if (n == 1){
            return 1;
        }
        return f1(n-1) + f1(n-2);
    }

通过递归的代码发现,其实有很大一部分是重复算的,如果n趋近于无限大,那么就有一半是重复计算的。


遍历解法

遍历的方式相比于递归的方式时间复杂度好很多,为O(n)
代码如下:

    /**
     * 采用遍历的方式实现
     * 时间复杂度为O(N)
     * @param n
     * @return
     */
    public static int f2(int n){
        int f0 = 0;
        if (n == 0) {
            return f0;
        }
        int f1 = 1;
        if (n == 1) {
            return f1;
        }
        int f2 = 0;
        for (int i=2; i<=n; i++){
            f2 = f0 + f1;
            f0 = f1;
            f1 = f2;
        }
        return f2;
    }

但是遍历的方式还不是时间复杂度最低的解决方案!


矩阵解法

实现的推导原理如下:
数列的递推公式为:f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)
用矩阵表示为:
在这里插入图片描述
进一步,可以得出直接推导公式:
在这里插入图片描述
也有如下的推导(这一块不是很理解,懂的可以帮忙在评论区解释一下哈):
在这里插入图片描述
矩阵的解法时间复杂度为O(logn)
代码如下:

    /**
     * 采用矩阵的解法
     * 时间复杂度为O(logN)
     * @param n
     * @return
     */
    public static int f3(int n){
        if (n == 0){
            return 0;
        }
        int[][] fbnq = fbnq(n);
        return fbnq[0][1];
    }

	/*矩阵处理核心代码*/
    private static final int[][] UNIT = {{1,1}, {1,0}};
    private static int[][] fbnq(int n){
        if (n == 1){
            return UNIT;
        }
        if (n % 2 == 0){
            int[][] matrix = fbnq(n / 2);
            return matrixMultiply(matrix, matrix);
        }else {
            int[][] matrix = fbnq((n-1) / 2);
            return matrixMultiply(UNIT, matrixMultiply(matrix, matrix));
        }
    }

	/*矩阵乘法*/
    private static int[][] matrixMultiply(int[][] a, int[][] b){
        int rows = a.length;
        int cols = b[0].length;
        int[][] matrix = new int[rows][cols];
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < b[0].length; j++) {
                for (int k = 0; k < a[i].length; k++) {
                    matrix[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        return matrix;
    }

测试

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println("========"+i+"========");
            System.out.println("递归方式:" + f1(i));
            System.out.println("遍历方式:" + f2(i));
            System.out.println("矩阵二分的方式:" + f3(i));
        }
    }

奶思

猜你喜欢

转载自blog.csdn.net/Lin_wj1995/article/details/82872644