典型动态规划问题:斐波那契数列

183 阅读2分钟

正题

剑指 Offer 10- I. 斐波那契数列

写一个函数,输入 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

解析:

动态规划解法

其实这是一个非常简单的初级算法应用题,求斐波那契数列的第N项。其实斐波那契额数列就是一个典型的动态规划解决的问题案例之一。

设定 dpList 长度为 N,那么每一个元素即位当前第n项的值。

默认 dpList[0] = 0 dpList[1] = 1, 从 2 开始

则有:

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    let dpList = new Array(n).fill(0)
    dpList[0] = 0
    dpList[1] = 1
    const MOD = 1000000007;
    for (let index = 2; index <= n ; index++) {
        dpList[index] = (dpList[index - 2] + dpList[index - 1]) % MOD
    }
    return dpList[n]
};

元素交换解法

动态规划有一点不好的就是需要开辟数组空间,如果N非常大,那么 dpList的长度就会非常大。为了避免这一情况,我们可以采用交换元素的方法来求得,第N项。

由于我们不需要知道N前面的数是多少,那么我们就没有必要保存第N向前面的数,只需要知道 N -1N - 2 分别是多少即可算出第N项

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