[路飞]_前端算法第五十弹-剑指 Offer 10- I. 斐波那契数列

547 阅读2分钟

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

递归

递归方法非常简单,只需要把上面的提示写一下,然后判断一下终止条件即可。

var fib = function (n) {
    if (n < 2) return n;
    return (fib(n-1)+fib(n-2))%1000000007
};

但是在LeetCode提交的时候就会发现,当n=44时,就会显示超时,是因为这种算法中有大量的重复计算,导致时间复杂度巨大。所以我们需要进行改进,我们把已经计算过的数存起来,这样下次如果又遇到相同的数的时候,直接提取计算即可,不需要再算一次。

var fib = function (n) {
    let arr = new Array(n + 1);
    return help(n)
    function help(n) {
        if (n < 2) return n;
        if (arr[n]) return arr[n];
        let num = (help(n - 1) + help(n - 2)) % 1000000007
        arr[n] = num;
        return arr[n]
    }
};

我们只需要创建一个arr数组,长度为n+1,将已经计算过的数按下标存入即可。

迭代

有递归就有迭代,递归是从最后一个数向前递归,那我们要运用迭代,只需要从第一个数开始算起,依次保存三个数,前一个数,前两个数,便可计算出当前数。

var fib = function (n) {
    if (n < 2) return n;
    let q = 0, p = 0, s = 1;
    for (let i = 2; i <= n; i++) {
        q = p;
        p = s;
        s = (p+q)%1000000007
    }
    return s
};