斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……
在数学上,斐波纳契数列以如下被以递归的方法定义:
F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>2,n∈N)*
一、递归
递归:从顶部开始将问题分解,通过解决掉所有分解的小问题来解决整个问题;
第一种当n较大时很快产生栈溢出
function Fibonacci(n){
// 第一种 递归,面试必败 斐波那契数列递归的时候会造成大量的重复计算
if(n<=0){
return 0
}
if(n==1||n==2) return 1
return Fibonacci(n-1)+Fibonacci(n-2)
}
--------------------------------------------------
// 优化版本,不会发生栈溢出
function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
if( n <= 1 ) {return ac2};
return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}
二、递推(动态规划)
动态规划:从底部开始解决问题,将所有小问题解决掉,然后合并成一个整体解决方案,从而解决掉整个大问题;
function Fibonacci(n){
if (n === 0) {
return 0;
}
if (n === 1) {
return 1;
}
let a = 0,
b = 1;
for (let i = 2; i < n; ++i) {
let c = a + b;
a = b;
b = c;
}
return a + b;
}
-------------------------------------------------
// 给定最初的值,通过不断累加,达到效果
function Fibonacci(n){
if (n===1 || n===2) {
return 1;
}
let ac1 = 1, ac2 = 1;
for (let i = 2; i < n; i++){
[ac1, ac2] = [ac2, ac1 + ac2];
}
return ac2;
}
三、generator 生成器
比较新奇的想法
function* fibonacci() {
let [prev, curr] = [1, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
function Fibonacci(n){
if (n===1 || n===2) {
return 1;
}
let ac = 0;
const fibo = fibonacci();
for (let i = 2;i < n; i++) {
ac = fibo.next()
}
return ac.value;
}
------------------------------------------------------------------
生成器。参考 Mr.Cool
原文链接:https://blog.csdn.net/qq_39300332/article/details/80000837
生成器详情使用:生成器实现斐波那契列–大佬分析的很有道理
阮一峰详解生成器:ES6生成器
四、ES6尾部优化
在ES6规范中,有一个尾调用优化,可以实现高效的尾递归方案。
ES6的尾调用优化只在严格模式下开启,正常模式是无效的。
'use strict'
function fib(n, current = 0, next = 1) {
if(n == 0) return 0;
if(n == 1) return next; // return next
console.log(`fibonacci(${n}, ${next}, ${current + next})`);
return fib(n - 1, next, current + next);
}