LeetCode-509. 斐波那契数

145 阅读2分钟

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

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

给定 n ,请计算 F(n) 。

示例 1:

输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

示例 2:

输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2

示例 3:

输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

提示:

  • 0 <= n <= 30

解题思路

1.递归普通版 先来个前端的最经典的解题思路,也就是不考虑任何优化的解题思路,通过递归去实现当前数字由上两个数字相加

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

2.递归进阶版 其实上面的这两种解题方法是存在问题,一方面是很多数字被重复计算两次,第二个问题是在js中如果当前方法没有被彻底执行完,那么当前调用的方法会一直存在调用栈中占用内存资源。ECMAScript 6规范新增了一项内存管理优化机制,让JavaScript引擎在满足条件时可以重用栈帧。这个就是尾调用优化,尾调用优化需要满足以下几个条件:代码要在严格模式下执行;外部函数的返回值是对尾函数的调用;尾调用函数返回后不需要执行额外的逻辑;尾调用不是引用外部函数作用域中自由变量的闭包。

'use strict'
var fib = function(n) {
    return fibImpl(0, 1, n)
};
var fibImpl = function (a, b, n) {
    if (n === 0) return a
    return fibImpl(b , a + b, n - 1)
}
  1. 利用数组存储每一次的值 我们可以利用一个数组把每次累加的和存起来,然后在0和1的时候做一个特判就好了
var fib = function(n) {
    let retArr = []
    for (let i = 0; i <= n; i++) {
        if (i < 2) {
            retArr[i] = i
        } else {
            retArr[i] = retArr[i-1] + retArr[i-2]
        }
    }
    return retArr[n]
}