经典递归问题:青蛙跳台阶,跳1个,2个或者3个
Posted 纵横千里,捭阖四方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典递归问题:青蛙跳台阶,跳1个,2个或者3个相关的知识,希望对你有一定的参考价值。
这个问题经常在各类面试中看到。一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
我们知道如果要写递归代码,那一定要先找到递归公式,这个找法,一个是画执行时的栈结构图来看,一个是从小到大来分析。我们看一下从小到大的过程:
从这里我们可以归纳出,递推公式是f(n)=f(n-1)+f(n-2),然后就可以根据三步走策略来写代码了:
1、确定递归函数功能
假设 f(n) 的功能是求青蛙跳上一个n级的台阶总共有多少种跳法,代码如下:
int f(int n)
2、找出递归结束的条件
求递归结束的条件,直接把 n 压缩到很小很小就行了,因为 n 越小,我们就越容易直观着算出 f(n) 的多少,所以当 n = 1时,你知道 f(1) 为多少吧?够直观吧?即 f(1) = 1。代码如下:
int f(int n)
if(n == 1)
return 1;
3.找出函数的等价关系式
每次跳的时候,青蛙可以跳一个台阶,也可以跳两个台阶,也就是每次跳的时候,小青蛙有两种跳法。
第一种跳法:第一次我跳了一个台阶,那么还剩下n-1个台阶还没跳,剩下的n-1个台阶的跳法有f(n-1)种。
第二种跳法:第一次跳了两个台阶,那么还剩下n-2个台阶还没,剩下的n-2个台阶的跳法有f(n-2)种。
所以,小青蛙的全部跳法就是这两种跳法之和了,即 f(n) = f(n-1) + f(n-2)。至此,等价关系式就求出来了。于是写出代码:
int f(int n)
if(n <=2 )
return n;
return f(n-1) + f(n-2);
代码看上去没问题对不对?其实是有和斐波那契数列一样的问题的,当 n = 2 时,显然会有 f(2) = f(1) + f(0)。我们知道,f(0) = 0,按道理是递归结束,不用继续往下调用的,但我们上面的代码逻辑中,会继续调用 f(0) = f(-1) + f(-2)。这会导致无限调用,进入死循环。
关于递归结束条件是否够严谨问题是递归算法的重要一环,有很多人在使用递归的时候,由于结束条件不够严谨,导致出现死循环。我们这里再补充n=2的情况就行了,代码如下:
int f(int n)
//f(0) = 0,f(1) = 1,等价于 n<=2时,f(n) = n。
if(n <= 2)
return n;
return f(n-1) + f(n-2);
那结束条件该怎么确定呢?其实最简单的方式就是写几个试一试,n足够小的时候也不过为 0 1 2 3 这几个种情况,或者是执行结束或者开始的时候几个元素,带进去试一试看看对不对就行了。
如果一次还能跳3个呢?
拓展如果这里说青蛙每次可以跳1个,2个,或者3个,那该怎么做呢?
一共有n个台阶,那青蛙第一次可以有几种跳法呢?很显然第一次可以选择跳1个,2个,3个,那剩余的台阶数是多少呢?是n-1,n-2,n-3个。而剩余台阶不管是多少个,都可以按照f(n)一样的逻辑来处理,也就是f(n-1)+f(n-2)+f(n-3)。所以我们就得到了递推公式f(n)=f(n-1)+f(n-2)+......+f(n-3)。这明显也是一个递归过程。
我们前面说了,必须处理结束时的场景,所以f(0),f(1),f(2)都要单独标记一下,所以最终代码就是:
int jump(int n)
if(n<=2)return n;
return f(n-1)+f(n-2)+f(n=3);
以上是关于经典递归问题:青蛙跳台阶,跳1个,2个或者3个的主要内容,如果未能解决你的问题,请参考以下文章
递归经典:汉诺塔问题和青蛙跳台阶的三个问题(爆肝的数学推理步骤以及详细代码)