【数据结构】——斐波那契数列

求斐波那契数列的第N项。

斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368…

这个数列从第3项开始,每一项都等于前两项之和。
f ( n ) = { 0 n=0 1 n=1 f ( n − 1 ) + f ( n − 2 ) n>1 f(n) = \begin{cases} 0 & \text{n=0} \\[2ex] 1 & \text{n=1}\\[2ex] f(n-1)+f(n-2) & \text{n>1} \end{cases} f(n)=01f(n1)+f(n2)n=0n=1n>1

解决方案1:递归

    /**
     * 递归
     *
     * @param n 第N项
     * @return 结果:当n=0为0,当n=1为1
     */
    private static long recursiveFibonacci(int n) {
        if (n <= 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        return recursiveFibonacci(n - 1) + recursiveFibonacci(n - 2);
    }

解决方案2:顺序循环递推求解,时间复杂度 O(n)

    /**
     * 顺序循环递推求解
     */
    private static long cycleFibonacci(int n) {
        if (n <= 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int n0 = 0;
        int n1 = 1;
        int fibN = 0;
        for (int i = 2; i <= n; i++) {
            fibN = n0 + n1;
            n0 = n1;
            n1 = fibN;
        }
        return fibN;
    }

解决方案3:公式求解

    /**
     * 公式求解
     */
    private static long formulaFibonacci(int n) {
        double temp = Math.sqrt(5.0);
        double result = (Math.pow((1 + temp) / 2, n) - Math.pow((1 - temp) / 2, n)) / temp;
        return (long) result;
    }

解决方案4:矩阵求解
有一个数学公式:

{ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) } \begin{Bmatrix}f(n) &amp; f(n-1) \\ f(n-1) &amp; f(n-2)\\ \end{Bmatrix} {f(n)f(n1)f(n1)f(n2)} = { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110} n-1

证明此公式:

n=2 时 { f ( 2 ) f ( 1 ) f ( 1 ) f ( 0 ) } \begin{Bmatrix}f(2) &amp; f(1) \\ f(1) &amp; f(0)\\ \end{Bmatrix} {f(2)f(1)f(1)f(0)} = { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110}

{ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) } \begin{Bmatrix}f(n) &amp; f(n-1) \\ f(n-1) &amp; f(n-2)\\ \end{Bmatrix} {f(n)f(n1)f(n1)f(n2)} = { f ( n − 1 ) f ( n − 2 ) f ( n − 2 ) f ( n − 3 ) } \begin{Bmatrix}f(n-1) &amp; f(n-2) \\ f(n-2) &amp; f(n-3)\\ \end{Bmatrix} {f(n1)f(n2)f(n2)f(n3)} * { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110}

{ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) } \begin{Bmatrix}f(n) &amp; f(n-1) \\ f(n-1) &amp; f(n-2)\\ \end{Bmatrix} {f(n)f(n1)f(n1)f(n2)} = { f ( n − 2 ) f ( n − 3 ) f ( n − 3 ) f ( n − 4 ) } \begin{Bmatrix}f(n-2) &amp; f(n-3) \\ f(n-3) &amp; f(n-4)\\ \end{Bmatrix} {f(n2)f(n3)f(n3)f(n4)} * { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110} 2

{ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) } \begin{Bmatrix}f(n) &amp; f(n-1) \\ f(n-1) &amp; f(n-2)\\ \end{Bmatrix} {f(n)f(n1)f(n1)f(n2)} = { f ( 2 ) f ( 1 ) f ( 1 ) f ( 0 ) } \begin{Bmatrix}f(2) &amp; f(1) \\ f(1) &amp; f(0)\\ \end{Bmatrix} {f(2)f(1)f(1)f(0)} * { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110} n-2

{ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) } \begin{Bmatrix}f(n) &amp; f(n-1) \\ f(n-1) &amp; f(n-2)\\ \end{Bmatrix} {f(n)f(n1)f(n1)f(n2)} = { 1 1 1 0 } \begin{Bmatrix}1 &amp; 1 \\ 1 &amp; 0\\ \end{Bmatrix} {1110} n-1

    /**
     * 矩阵求解
     */
    private static long matrixFibonacci(int n) {
        if (n <= 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int[][] matrix = INIT;
        while (n-- - 2 > 0) {
            matrix = matrixMultiply(matrix, INIT);
        }
        //最终结果为矩阵相乘之后的第一个元素
        return matrix[0][0];
    }

解决方案5:递归矩阵
利用乘方的特性,时间复杂度O(logn)
在这里插入图片描述

    /**
     * 递归矩阵
     */
    private static int[][] recursiveMatrixFibonacci(int n) {
        if (n <= 0) {
            return new int[][]{{0, 0}, {0, 0}};
        }
        if (n == 1) {
            return INIT;
        }
        // n是偶数
        if ((n & 1) == 0) {
            int[][] matrix = recursiveMatrixFibonacci(n >> 1);
            return matrixMultiply(matrix, matrix);
        }
        // n是奇数
        int[][] matrix = recursiveMatrixFibonacci((n - 1) >> 1);
        return matrixMultiply(matrixMultiply(matrix, matrix), INIT);
    }

解决方案6:优化矩阵求解,不使用递归

    /**
     * 优化矩阵求解
     */
    private static long advancedMatrixFibonacci(int n) {
        if (n <= 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int[][] temp = INIT;
        // 单位矩阵
        int[][] result = {{1, 0}, {0, 1}};
        int m = n - 1;
        while (m > 0) {
            if ((m & 1) == 1) {
                result = matrixMultiply(temp, result);
            }
            temp = matrixMultiply(temp, temp);
            m >>= 1;
        }
        return result[0][0];
    }
public class Fibonacci {

    /**
     * f(n) = INIT矩阵的(n-1)次方
     */
    private static final int[][] INIT = {{1, 1}, {1, 0}};

    public static void main(String[] args) {
        int[] nums = new int[]{0, 10, 11};
        for (int num : nums) {
            System.out.println(recursiveFibonacci(num));
            System.out.println(cycleFibonacci(num));
            System.out.println(formulaFibonacci(num));
            System.out.println(matrixFibonacci(num));
            int[][] m = recursiveMatrixFibonacci(num);
            System.out.println(m[0][1]);
            System.out.println(advancedMatrixFibonacci(num));
            System.out.println("--------------");
        }
    }

    /**
     * 矩阵相乘
     *
     * @param m r1*c1
     * @param n c1*c2
     * @return 新矩阵, r1*c2
     */
    private static int[][] matrixMultiply(int[][] m, int[][] n) {
        int rows = m.length;
        int cols = n[0].length;
        int[][] r = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                r[i][j] = 0;
                for (int k = 0; k < m[i].length; k++) {
                    r[i][j] += m[i][k] * n[k][j];
                }
            }
        }
        return r;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值