斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(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)
}
利用数组存储每一次的值我们可以利用一个数组把每次累加的和存起来,然后在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]
}