问题,一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
这个问题明显是由跳台阶进阶而来,我们由于已经做过跳台阶问题,先进行简单分析。
首先可知,第一阶台阶只会有一种跳法;,第二阶可能有两种跳法,分别为两次一步、一次两步两种。
-
若楼梯阶级 n = 3
-
跳 1 步到 3:剩下的是第二步没跳,起始跳到第二步只有两种种
-
跳 2 步到 3:,剩下的是第一步没跳,起始跳到第一步只有一种
-
跳 3 步到 3:剩下0步没跳,所以只有一种跳法
-
-
所以得出结论,若三级台阶,则跳法一共有 1 + 1 + 2 = 4种,可以得出以下结论
f(3) = f(2) + f(1) + 1;
当然,我们还可以继续分析台阶级数为四,为五的情况,最终可以通过分类讨论,得出以下结论:
-
若楼梯阶级 n (n >= 3)
-
跳 1 步到 n:剩下的是第 n - 1 步没跳,起始跳到第 n - 1 步设它为 pre1 种
-
跳 2 步到 n:剩下的是第 n - 2 步没跳,起始跳到第 n - 2 步设它为 pre2 种
-
跳 3 步到 n:剩下的是第 n - 3 步没跳,起始跳到第 n - 3 步设它为 pre3 种
-
....
-
一直到 跳n-1到n:剩下的是第 1 步没跳,起始跳到第 n - 1 步就只有一种跳法。
-
-
最终得出以下结论
-
f(n) = f(n-1) + f(n-2) +...+ f(1) + 1;
-
f(n -1) = f(n-2) +...+ f(1) + 1;
-
两者相减 则 f(n) - f(n -1) = f(n-1) -> f(n) = 2f(n-1);
-
-
得到计算公式,f(n) = 2f(n-1) (n >=2 ),得到公式以后,解决方案就变得很简单了。
所以解决方案也有两者方法,一种递归,一种利用公式进行循环运算。
第一种解决方案,便是采用递归的方式,代码如下
public static int firstJumpFloorN(int target) {
if(target < 0){
return 0;
}
if(target == 1){
return 1;
}
return firstJumpFloorN(target - 1 ) * 2;
}
第二种便是类似于斐波拉契数列,代码如下
public static int secondJumpFloorN(int target) {
if(target < 0){
return 0;
}
if(target == 1){
return 1;
}
int one = 1;
int two = 2;
for (int i = 2; i <= target; i++){
two = one * 2;
one = two;
}
return two;
}
完整代码如下
public class MainJumpFloorN {
public static void main(String[] args) {
}
/**
* 递归调用
* @param target
* @return
*/
public static int firstJumpFloorN(int target) {
if(target < 0){
return 0;
}
if(target == 1){
return 1;
}
return firstJumpFloorN(target - 1 ) * 2;
}
/**
* 累加调用
* @param target
* @return
*/
public static int secondJumpFloorN(int target) {
if(target < 0){
return 0;
}
if(target == 1){
return 1;
}
int one = 1;
int two = 2;
for (int i = 2; i <= target; i++){
two = one * 2;
one = two;
}
return two;
}
}