斐波那契数

493 阅读1分钟

斐波那契数

斐波那契数列的任意一项都可以叫做斐波那契数。斐波那契数列是指这样一个数列: 0112358132134、......
数列的第1项和第2项的数值分别为01,往后每一项的数值是前两项的和。
斐波那契数的边界条件为:F(0)=0,F(1)=1;
递推关系是:F(n)=F(n-1)+F(n-2);

递归

当我们知道一道题有递推关系,并且存在边界条件(出口),那么可以采用递归的方式解题
    function fib(n) {
        if (n === 0) return 0;
        else if (n === 1) return 1;
        return fib(n - 1) + fib(n - 2);
    }
采用递归是最容易做出来,但也是耗时最长,时间复杂度O(2^(n/2))到O(2^n)
可以采用尾递归来降低时间复杂度,可达O(n)
    function fib(first, second, n) {
        if (n < 2) return n;
        if (n === 2) return first + second;
        return fib(second, first + second, n - 1);
    }
    fib(0, 1, n);

动态规划

老实讲,对于动态规划,还是不清楚如何运用。
虽然有时候谈论题目的时候会因为这道题做过或者看过解题思路,知道它该使用动态规划去解决。
但深究时,总觉得是因为看过这道题用动态规划解答而使用动态规划;而不是因为理解动态规划的思想而对这道题采用动态规划的方法。
......唉,扯远了

动态规划基本方程三个条件

状态转移方程
最优值函数
边界条件
举个例子: 从一数列中找前n个数中最大的数,势必要进行比较记录较大的数,
    MAX_NUM<n+1> = (X<n+1> > MAX_NUM<n>) ? X<n+1> : MAX_NUM<n>
这就是一个状态转移方程,递推关系
(已知n阶段的状态:MAX_NUM<n>,执行的决策:(X<n+1> > MAX_NUM<n>) ? X<n+1> : MAX_NUM<n>,就可以得到n+1的状态)

使用动态规划思想解答

    function fib(n) {
        // 已知值
        if (n < 2) return n;
        // 边界条件F(0) = 0;F(1) = 1;
        let first = 0, second = 1, result = null;
        // 状态转移:前两项值的和等于第三项
        for(let i = 2; i <= n; i++) {
            result = first + second;
            first = second;
            second = result;
        };
        return result;
    }
牢骚太盛防肠断,风物长宜放眼量。🏝🏝🏝