【LeetCode】斐波那契数列 - 递归 - 缓存递归 - 动态规划 - 矩阵快速幂 - 通项公式 - JavaScript描述 - 相关问题拓展 - 爬楼梯

1. 题目来源

509. 斐波那契数
这题的要求是0 <= n <= 30 (用无脑递归可以通过)
剑指 Offer 10- I. 斐波那契数列
这题的要求是0 <= n <= 100 (用无脑递归不可以通过)

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。

3. 题目解析

3.1 暴力递归

就直接暴力递归,虽然能解决问题,但是数字一大复杂度就特别高。

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
   
    if( n === 0) return 0
    if(n === 1) return 1
    return fib(n-1) + fib(n-2)
};

这种无脑解法可以初步解决问题,但是我们仔细思考一下,他的优化空间很大

首先一个问题就是这里重复递归的次数实在是太多了,比如说我要求fib(5),
如图可视,我们重复求解了多次fib(2)和fib(3)其实这是没有必要的,我们可以用一个缓存cache,来将我们求过了的fib(n)保存在缓存中,下次用到他的时候直接读取他的值就可以了,而不是再重新递归求值,在这里插入图片描述

3.2 递归 + 缓存

在这里插入图片描述

/**
 * @param {number} n
 * @return {number}
 */
 
// 首先定义一个缓存数组,用来存放求出来的Fib(k)的值 k = 2, ... , n
let cache = []

var fib = function(n) {
   
	// 1. 如果缓存中已经有这个值了,就直接返回,不要再递归求值了
    if(cache[n] !== undefined){
    return cache[n] }
    // 两个初始值
    if(n === 0) return 0
    if(n === 1) return 1
    
    // 递归求得fib(n)
    let v = (fib(n-1) + fib(n-2)) %1000000007
    
    // 将fib(n)保存在cache[n]的位置
    cache[n] = v
    // 返回fib(n)
    return v
};

3.3 动态规划

加了缓存的递归虽然可以通过测试了,减少了重复的递归计算,但是利用了额外的空间来存储缓存,还有进一步优化的空间

在这里插入图片描述

var fib = function(n) {
   
	if(n<2) return n;
	
    let i = 0;
    let j = 1;
    let sum = 1;
    
    // 每循环一次,将i和j的值相加得到sum放在j后面,将i和j都后移一位
    for(let k = 2; k <= n; k++){
   
        i = j;
        j = sum;
        // sum 是i和j的和 保存在i和j的后面
        sum = (i + j) % 1000000007;
    }
    
    return sum ;
};

在这里插入图片描述

3.4 矩阵快速幂

Leetcode上面的题解!!!扩展思路!!
在这里插入图片描述
计算出 M n M^n Mn 之后,

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值