斐波那契数列

斐波那契数列:费波那契数列由0和1开始,之后的费波那契系数就是由之前的两数相加而得出
举例: 0 1 1 2 3 5 8 …..


  /**
     * @name  fib
     * @description
     *    求斐波那契数列第 n 项的值
     *    斐波那契数列为  0  1 1 2 3 ...  第 0 项为  0;
     *
     * @param n
     * @returns  Number 
     * @递归的缺点当超过一定的值时,会造成栈溢出
     */

       function fib( n ) {

            if( typeof n !== 'number' || n < 0) {
                      return '';
                  }
             var fib_n  = function( cur, next, n) {

                   if(n === 0) {
                       return cur;
                   } 
                   else {
           // 调换参数位置并且 进行 next + cur 累加操作
              return fib_n(next, next + cur, n - 1)
                   }

           };

           return fib_n( 0 , 1 , n);
       }
        /**
     * @name  fibBetter
     * @description
     *    求斐波那契数列第 n 项的值
     *    斐波那契数列为  0  1 1 2 3 ...  第 0 项为  0;
     *
     * @param n
     * @returns  Number 
     * @循环不会造成栈溢出
     */

       function fibBetter( n ) {
         if( typeof n !== 'number' || n < 0) {
           return '';
         }
         function fib_n(cur, next, index) {
           while (index >= 0) {
              var item = cur;
              cur = next;
              next = item + next;
              index--;
           }
           return cur;
         }
        return fib_n(0, 1, n - 1);
      }

斐波那契数列对应的台阶问题
假设有 n 阶台阶, 一次可以上小于等于m 个台阶, 问有多少种上法 ?

先假设 a 情景 只有 1 个台阶 一次可以上的台阶数定义为step, 且 0 < step <= 2的话, 一共有 1 种上法
假设 b 情景 只有 2 个台阶 一次可以上的台阶数定义为step, 且 0 < step <= 2的话, 一共有 2 种上法
假设 c 情景 只有 3 个台阶 一次可以上的台阶数定义为step, 且 0 < step <= 2的话,

那我们刚开始就只有 2 种 上法 即只上 1 个台阶 或只上 2 个台阶

再进一步假设我第一次只上了 1 个台阶,

后面的 2 阶台阶的上法不就等同于

前面假设的 b 情景的上法嘛, (暂且理解为简单的递归思想吧)

再假设我第一次上了 2 个台阶,剩下的 1 个台阶等同于 a 情景 ,

好了我这第一次能够上的台阶数假设完了,没有其他可能了,

那情景c的上法就是 情景a + 情景b 的上法,

情景 c, 一共有 3 种上法。

假设情景 d 有 4 个台阶 一次可以上的台阶数定义为step, 且 0 < step <= 2的话,

通过情景 c 的假设方法, 我们不难得出 情景 d , 一共有 5 种上法

总结以上的结果可以得出台阶数 n 跟方法之间 ,可以是一个对应的斐波那契数列,只不过第 0 项是一个 1,
这样总结后我们,
可以写出有n阶台阶 ,一次可以上的台阶数定义为step, 且 0 < step <= 2的话,求总共有几种上法的函数

      function step_2(n) {

                var   fib_n = function(curr, next, n) 
           {
            if (n === 0) 
           {
                return curr;    
           }
           else 
           {
              return fib_n(next, curr+next, n-1);
           }       

        return fib_n(1, 1, n);  //改动第0项为1即可
      } 

再来看看原先的问题
假设有 n 阶台阶, 一次可以上小于等于 m 个台阶, 问有多少种上法 ?
其实就是一道数学题!

假定 n <= m, 那对于前 n - 1个台阶每个都有两种走法,最后一个台阶必须走,那么就有 Math.pow(2, m - 1) 种走法。

剩下一种情况, n > m , 根据总结,容易发现,其实方法数等于

Math.pow(2, m - 1) 减去 Math(2, 0) + Math.(2, 1) .... + Math(2, m - n -1)的和

好的没有其他情况了。

   /**
     * @name sum
     * @descript
     *     为的是应对 m < n 的情况,
     *     求 Math(2, 0) + Math.(2, 1) .... + Math(2, m - n - 1)的和
     * @param m  总的台阶数
     * @param n  最大可以跨越的台阶数
     * @returns {number}
     */

      function sum( m, n) {

          var len = m - n;
              add = 0;

          // 第一次循环先判断len  然后 len = len - 1赋值后进入循环体
          while(len--) {
              add += Math.pow(2, len);
          }
          return add;
      }
    /**
     * @name  methods
     * @description
     *     参数必须是 number 类型 且 大于 0 ,为了便于理解 函数内没有写限制条件
     *     假设有 m 阶台阶,  一次可以上小于等于 n 个台阶, 问有多少种上法 ?
     *     
     *     分两种情况  m  <=  n  直接返回 Math.pow(2, m - 1);
     *     对于 m > n   直接返回  Math(2, m - 1) - sum(m , n);
     * @param m  总的台阶数 
     * @param n  最大可以跨越的台阶数
     * @returns {number}
     */


      function methods( m , n ) {
        var  ret, i;
             i  = m - 1;
        if ( m <= n) {
            ret = Math.pow(2,  i )
        } else {
            ret = Math.pow(2, i) - sum(m , n);
        }
        return  ret;
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值