js实现斐波那契数列的几种方式

首先介绍下斐波那契序列
0,1,1,2,3,5,8,...
就每一项的值都是前两项相加得到的。

方法一: 最常见的递归实现

function fn(n) {
    if(n === 0 || n === 1)
        return n;
    return fn(n-1) + fn(n-2);
}

console.log(fn(5))

代码优美逻辑清晰,但是有重复计算的问题.
如:当n为5的时候要计算fibonacci(4) + fibonacci(3),当n为4的要计算fibonacci(3) + fibonacci(2) ,这时fibonacci(3)就是重复计算了。
运行 fibonacci(50)会出现浏览器假死现象,毕竟递归需要堆栈,数字过大内存不够。

方法二: 使用闭包

改进递归-利用闭包特性把运算结果存储在数组里,避免重复计算

var fn = function () {
    let memo = [0, 1];
    let fib = function (n) {
        if (memo[n] == undefined) {
            memo[n] = fib(n - 2) + fib(n - 1)
        }
        return memo[n]
    }
    return fib;
}()

fn(50)

方法三:循环递推法

从下往上计算,首先根据f(0)和f(1)算出f(2),再根据f(1)和f(2)算出f(3),依次类推我们就可以算出第n项了,比递归的效率高很多

function fn(n) {
    let current = 0;
    let next = 1;
    let temp;
    for(let i = 0; i < n; i++) {
        temp = current;
        current = next;
        next += temp;
    }
    return current;
}

借助解构赋值省略temp中间变量

function fn(n) {
    let current = 0;
    let next = 1;
    for(let i = 0; i < n; i++) {
        [current, next] = [next, current + next];
    }
    return current;
}

方法四: 尾调用优化

function fn(n, current = 0, next = 1) {
    if(n == 0) return 0;
   // 或者  if(n == 0) return current;
    if(n == 1) return next;
    return fn(n - 1, next, current + next);
}

函数的尾调用与尾递归,具体请看这里
https://www.cnblogs.com/ZheOneAndOnly/p/11368056.html

posted @ 2021-06-28 09:28  进军的蜗牛  阅读(1373)  评论(0编辑  收藏  举报