美文网首页
算法题目-斐波那契数列问题

算法题目-斐波那契数列问题

作者: MacXin | 来源:发表于2018-02-27 16:30 被阅读0次

    (文章参考来源)

        https://zhidao.baidu.com/question/2115713113203375747.html

        https://www.jianshu.com/p/78243311b8ed

    题目

        有一对兔子,从出生后第3个月起每个月都生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 

        分析,每个月份的兔子数(单位:对)是:

        1

        1

        2(T1生了T2)

        3(T1生了T3)

        5(T1生了T4,T2生了T5)

        8(T1生了T6,T2生了T7,T生了T8)

        13(T4、T5也加入了生兔子大军)

        从数据可见,每个月的兔子数(单位:对)形成了菲波那切数列。

    javaScript code

    1) 正常递归版本

    function fibonacciFunc(n){

      if(n == 0)

        return 0

      else if(n == 1)

        return 1

      else

        return fibonacciFunc(n-1)+fibonacciFunc(n-2)

    }

    代码优美逻辑清晰。但是这个版本有一个问题即存在大量的重复计算。如:当n为5的时候要计算fibonacci(4) + fibonacci(3)当n为4的要计算fibonacci(3) + fibonacci(2),这时fibonacci(3)就是重复计算了。运行fibonacci(50)等半天才会出结果。

    2)for循环版本

    function fibonacci(n){

      let last = 1

      let last2 = 0

      let current = last2

      for(let i=1; i<= n; i++){

        last2 = last

        last = current

        current = last+last2

      }

      return current

    }

    这个版本没有重复计算问题,速度也明显快了很多。这并不代表循环比递归好。循环的问题在于状态变量太多,为了实现fibonacci这里使用了4个状态变量(last,last2,current,i)而状态变量 在写、修改、删除的过程中需要格外小心,它会让我有不安全感。状态变量多了阅读起来也不那么优美了。

    3)去除重复计算的递归版本

    function fib(n){

      function fib_(n, a, b){

        if(n == 0)

          return a

        else

          return fib_(n-1, b, a+b)

      }

      return fib_(n, 0, 1)

    }

    把前两位数字做成参数巧妙的避免了重复计算,性能也有明显的提升。n做递减运算,前两位数字做递增(斐波那契数列的递增),这段代码一个减,一个增,初看时有点费脑力。按照我的习惯一般是全增,让n从0开始到n。

    相关文章

      网友评论

          本文标题:算法题目-斐波那契数列问题

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