一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、…… ——百度百科
分析
斐波那契数列的一个数列:1,1,2,3,5,8,13,21,34,55,89...
划重点:这个数列从第3项开始,每一项都等于前两项之和
实现
递归
说!你是不是第一个想法也是递归实现..
function fibonacci1(n: number): number {
if (n === 1 || n === 2) {
return 1;
}
return fibonacci1(n - 1) + fibonacci1(n - 2);
}
测试
- fibonacci1(3); // => 2 ✅
- fibonacci1(5); // => 5 ✅
- fibonacci1(10); // => 55 ✅
- fibonacci1(100); // => 卒............
这个fibonacci1(100)直接让chrome 卒..., 原因最后再说..
尾递归调用
尾递归调用: 就是指在函数的最后一步调用自身函数
function fibonacci2(n: number, prev: number = 1, next: number = 1): number {
if (n === 1 || n === 2) {
return next;
}
return fibonacci2(n - 1, next, prev + next);
}
测试
- fibonacci2(3); // => 2 ✅
- fibonacci2(5); // => 5 ✅
- fibonacci2(10); // => 55 ✅
- fibonacci2(50); // => 12586269025 ✅
- fibonacci2(100); // => 354224848179262000000 ✅
循环
循环的算法逻辑:利用的是长度为3的滑块,【
prev1(前2个),prev2(前一个),cur(当前)】, 依次向后移动,这样的好处就是只需要遍历一遍,cur的计算也是从之前的缓存结果中取到的。
function fibonacci3(n: number):number | undefined {
if (n === 1 || n === 2) {
return 1;
}
let prev1 = 1;
let prev2 = 1;
let cur = 0;
for (let i = 3; i <= n; i++) {
cur = prev1 + prev2;
prev1 = prev2;
prev2 = cur;
}
return cur;
}
- fibonacci3(3); // => 2 ✅
- fibonacci3(5); // => 5 ✅
- fibonacci3(10); // => 55 ✅
- fibonacci3(50); // => 12586269025 ✅
- fibonacci3(100); // => 354224848179262000000 ✅
数学通用公式
公式内容
function fibonacci4(n: number):number {
if (n === 1 || n === 2) {
return 1;
}
const SQRT_FIVE = Math.sqrt(5);
return Math.round(1/SQRT_FIVE * (Math.pow(0.5 + SQRT_FIVE/2, n) - Math.pow(0.5 - SQRT_FIVE/2, n)));
}
测试
- fibonacci4(3); // => 2 ✅
- fibonacci4(5); // => 5 ✅
- fibonacci4(10); // => 55 ✅
- fibonacci4(50); // => 12586269025 ✅
- fibonacci4(100); // => 354224848179262000000 ✅
思考总结
为何递归fibonacci1(100);能到浏览器崩溃的地步...
递归算法分析 如图(图是盗的..🤭)
看的出来虽然递归写起来和理解起来很容易,但是会进行很多没必要的重复计算,导致运行时间超长.其时间复杂度达到了惊人的
O(2^n).
另外:
尾递归调用的时间复杂度为O(n);循环的时间复杂度为O(n);数学通用公式的时间复杂度为O(logn);
所以,以后再实现斐波那契数列,你知道该选择哪一个了吗?