美文网首页
算法练习01 记忆化斐波那契函数

算法练习01 记忆化斐波那契函数

作者: 多啦斯基周 | 来源:发表于2018-11-15 10:05 被阅读0次

    题目(2018-11-15)

    斐波那契数列指的是类似于下面的数列:

    1, 1, 2, 3, 5, 8, 13, ……
    

    也就是,第n个数是由前面两个数相加而来

    完成fibonacci函数,接受n作为参数,可以获取数列中第n个数,例如:

    fibonacci(1) // => 1
    fibonacci(2) // => 1
    fibonacci(3) // => 2
    ...
    

    实现

    想到的最简单的实现就是利用递归:

    const fibonacci = (n) => {
      if (n === 2 || n === 1) {
        return 1
      }
      return fibonacci(n - 1) + fibonacci(n - 2)
    }
    

    这样的问题时,当n比较大的时候(比如500),计算时间过长,程序会失去响应

    所以需要进行改进,需要利用缓存,空间换区时间,在计算时多传入一个cache对象,用于缓存计算过的数据:

    const fibonacci = (n, cache = {}) => {
      if (n <= 2) {
        return cache[n] = 1;
      }
      if (cache[n]) {
        return cache[n];
      }
      return cache[n] = fibonacci(n - 1, cache) + fibonacci(n - 2, cache)
    };
    
    console.time('1st');
    console.log(fibonacci(1000));
    console.timeEnd('1st');
    // 4.346655768693743e+208
    // 1st: 1.26904296875ms
    
    console.time('2ed');
    console.log(fibonacci(1000));
    console.timeEnd('2ed')
    // 41 4.346655768693743e+208
    // 2ed: 0.637939453125ms
    

    通过实验,这样是行得通的。

    我们还可以进一步优化,由于缓存cache在每次计算都是需要反问的,也就是说cache是需要保留在内存中的,那么我们就可以构造一个闭包,让cache保留在闭包中,供递归时使用:

    const fibonacci = ((cache = {}) => n => {
      if (cache[n]) {
        return cache[n];
      }
      if (n <= 2) {
        return cache[n] = 1;
      }
      return cache[n] = fibonacci(n - 1) + fibonacci(n - 2);
    })();
    
    console.time('1st');
    console.log(fibonacci(1000));
    console.timeEnd('1st');
    // 4.346655768693743e+208
    // 1st: 0.6630859375ms
    
    console.time('2ed');
    console.log(fibonacci(1000));
    console.timeEnd('2ed')
    // 41 4.346655768693743e+208
    // 2ed: 0.186279296875ms
    

    多次试验后发现,采用闭包的计算速度还是要快于直接传参的计算速度的,尤其是非首次计算,相对于首次计算时,由于cache会保留在内存中,对计算速度的提高非常大

    参考

    相关文章

      网友评论

          本文标题:算法练习01 记忆化斐波那契函数

          本文链接:https://www.haomeiwen.com/subject/gsvefqtx.html