1.定义
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)
2. 递归实现以及性能思考
递归实现
var count = 0;var fibonacci = (n) => {
count++;
return n === 1 || n === 2 ? 1 : (fibonacci(n - 1) + fibonacci(n - 2))
};
fibonacci(10);console.log(count);//被调用109次
这是斐波那契数列最基本的递归实现。但是该递归实现方法复杂度过高。
对性能的思考
假如说n=5,那么可以用下图来表示计算的次数:
可以计算出方法被调用次数:
2^0 + 2^1 + 2^2 + ... + 2^(n-2) + 2^(n-3)+...+2^1
2^10 = 1024
2^20 = 1,048,576
当数量稍微大一点的时候计算机的cpu就不行了。那我们怎么优化这个方法呢?
3.优化方案
空间换时间思想
基于普通递归方法,我们可以把每次计算结果储存起来,如果计算过了就直接取值,没有计算才会调用计算
var count = 0;
var obj = {};
var fibonacci = (n) => {
count++;
if (n === 1 || n === 2) {
obj[n] = 1;
return 1;
}
if (obj[n]) {
return obj[n]
}
const res = (fibonacci(n - 1) + fibonacci(n - 2));
obj[n] = res;
return res;
};
fibonacci(10);
console.log(count);//该方法被调用17次es6解构实现
var fibonacci = (n) => {
let [a, b] = [0, 1];
for (let i = 0; i < n; i++) {
[a, b] = [b, a + b]
}
return a;
};
fibonacci(10);Array数组实现
Array(n).fill快速填充一个数组长度为n的数组
var fibonacci = () => {
const res = Array(n).fill().reduce(([a, b]) => { return [b, a + b] }, [0, 1]);
return res[0];
};
fibonacci(10);generator实现
function* getFibonacci() { let [a, b] = [0, 1]; while (true) { [a, b] = [b, a + b]; yield a; }}var fibonacci = (n) => { let res = { value: 0 }; const fibo = getFibonacci(); for (let i = 0; i < n; i++) { res = fibo.next(); } return res.value;};fibonacci(10);ES6解构,Array,Generator这三种原理都是一样的,只不过套了不同的壳子而已。