几个经典递归问题用js实现

Question1—Fibonacci数列第N项

ana1=1a2=1an+2=an+1+ann1
var fib = function (n){
  if(n<=2){
    return 1;
  }
  return fib(n-1) + fib(n-2);  
}
console.log(fib(5));
上面是递归实现。

var fib = function (n){
  var a1=1,a2=1,a3=0;
  if(n<=2){
    return 1;
  }
  for(var i = 0;i < n-1;i++){
    a3 = a1 + a2;
    a1 = a2;
    a2 = a3;
  }
  return a3;  
}
console.log(fib(5));
上面是循环实现。

Question2—一共10级楼梯,每次可以走一步或两步,求一共多少种走法。

思路:

要想走到N(N=10)级,可以分为2种情况。

  1. 从n-2级迈两步
  2. 从n-1级迈一步

那么对于n-2和n-1的情况也是各自分为两种,以此类推。

那么走法的和就是n-2的走法和n-1的走法之和。

那么递归到最基本的(当前人在第0阶台阶)

第0阶台阶:0

第1阶台阶:1

第2阶台阶:2(1+1或者2)

得到公式,也就是斐波那契数列。

f(n)=f(n1)+f(n2)


var fib = function (n){
  if(n == 1){
    return 1;
  }else if(n==2){
    return 2;
  }else if(n>2){
    return fib(n-1) + fib(n-2);
  }
}
console.log(fib(10));

Question3—1个细胞,一个小时分裂一次,生命周期是3小时,求n小时后容器内,有多少细胞。


思路:

细胞的生存周期是3个小时,那我们就可以把细胞在题目中状态分为以下几个状态:

  • a:刚分裂态——由前一小时的a,b,c分裂出
  • b:分裂1小时态——由前一小时a长成
  • c:分裂2小时态——前一小时b长成
  • d:分裂3小时态——死亡的细胞。前一小时c长成,和之前的d一起组成。

那么,我们就可以根据细胞状态设定函数。分析每一个状态的来源是哪里即可。

a(t)=a(t1)+b(t1)+c(t1)b(t)=a(t1)c(t)=b(t1)d(t)=d(t1)+c(t1)

容器中存活的细胞数目就是a、b、c三种状态数量的总和。

var afib = function (n){
  if(n===0){return 1;} //初始的那个细胞
  return afib(n-1)+bfib(n-1)+cfib(n-1);
}
var bfib = function(n){
  if(n===0){return 0;} //一个小时之后才会生成
  return afib(n-1);
}
var cfib = function(n){
  if(n===0||n===1){return 0;} //前两小时还没生成
  return bfib(n-1);
}

var time = 3;
console.log(afib(time)+bfib(time)+cfib(time));


总结:

递归的两个必要因素:

     递归方程,递归结束条件。

算法核心:

  • 在有限次可预见性结果中,找到结果与上一次结果之间的关系。
  • f(n)与f(n-1)的关系有时候很简单,如同走楼梯,状态单一;又有时如同细胞分裂,多种状态组合影响结果。
  • 关键在于梳理清楚本次结果和上一次结果的关系有哪些方面或是因素。
  • 在草稿纸上写出前几次的结果,或者画图,这样更容易找到规律,这种规律实际上就是递归方程。
  • 在算法的分析中,当一个算法中包含递归调用时,其时间复杂度的分析会转化成为一个递归方程的求解。



  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 递归是一种编程技巧,其中一个函数调用自身。在 JavaScript 中,递归方法可以用来解决复杂的问题,并使代码更简洁易读。 递归的基本模型包括以下几个步骤: 1. 定义递归终止条件:当递归达到一定的深度时,必须终止递归。 2. 分治:将问题分解为规模更小的子问题。 3. 调用自身:通过解决子问题来解决整个问题。 4. 记录结果:在递归的过程中,记录每一步的结果。 下面是一个简单的递归例子,计算阶乘: ``` function factorial(n) { if (n === 0) { return 1; } return n * factorial(n - 1); } ``` 在这个例子中,递归终止条件是 `n` 为 0,分治的子问题是计算 `n-1` 的阶乘,调用自身的方式是通过函数 `factorial` 调用,并将计算结果返回。 ### 回答2: 递归是一种在编程中常见的技巧,特别在JavaScript中,递归方法经常被用来解决问题递归是指一个函数调用自身的过程。下面是关于JavaScript递归方法的一些重要信息: 1. 递归方法必须包含一个终止条件,否则函数将无限地调用自身。这个终止条件通常是某个特定条件的判断,一旦满足了该条件,递归将停止。 2. 递归方法必须能够将问题分解为更小的子问题,同时保持问题的解决方案是相同的。 3. 递归方法可以方便地解决一些复杂的问题,例如树和图的遍历,阶乘计算等。 4. 使用递归方法时需要小心,因为它可能会导致性能问题递归过程中使用大量的函数调用,可能导致堆栈溢出。 5. 尽管递归方法可以让代码更简洁和易于理解,但在某些情况下,使用循环可能更高效和可维护。因此,在选择使用递归方法之前,需要仔细权衡。 总的来说,JavaScript的递归方法是一种强大而灵活的编程技巧,可以解决各种问题。但在使用时需要注意终止条件和性能问题,以确保代码的正确性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值