题1:变态跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
示例
输入
3
返回值
4
解析:
-
规律分析:
台阶 : 跳法 0 0 1 1 2 2 (1,2) 3 4 (111,12,21,3) 4 8 (1111,211,112,121,22,31,13,4) ...以此类推
-
根据上一题思路逆向推导:
-
假设青蛙已经跳到了第n级台阶,那么它有可能最后一步是在:
-
第n-1级台阶
- 此时有f(n-1)种跳法
-
第n-2级台阶
-
此时有f(n-2)种跳法
…以此类推
-
-
第n-n级台阶
- 此时有f(n-n)种跳法,f(0) = 1,一步登天
-
~
-
上述台阶跳上第n级台阶
-
-
公式推导:
-
根据上述思路,用f(n)来表示跳n级台阶的跳法数量:
f(1)=1表示跳1级台阶的跳法数量; f(2)=2表示跳2级台阶的跳法数量; f(3)=f(2)+f(1)+1 可以递推出 f(n)=f(n-1)+f(n-2)+ ... +f(1)+1 ; 同理 f(n-1)=f(n-2)+f(n-3)+ ... +f(1)+1 ; 将两式相减可以求出递推公式: f(n)-f(n-1)=f(n-1), 即f(n)=2*f(n-1)
-
此时可以得出:
|—— 1, (n=0) | f(n) =|—— 1, (n=1) | |—— 2*f(n-1) (n>=2,n为整数)
-
-
逻辑带师:
转自牛客:
每个台阶都有跳与不跳两种情况(除了最后一个台阶),最后一个台阶必须跳。所以共用2^(n-1)中情况
-
实现方式:
-
既然已经求出通项公式,自然可以用递归方法解决。
-
但是经常用递归消耗大,可以用数组优化
用数组优化此类递归的方式为动态规划思想
-
解答:
//经典递归方法
public int JumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * JumpFloorII(target - 1);
}
}
//动态规划优化
public int JumpFloorII_dp(int target) {
if(target==0){ //如果为0层台阶时,返回0
return 0;
}
int a[] = new int[target+2]; //加2的原因是下面的a数组要初始化到第三个元素
int b=3; //如果小于3的话直接取值
a[0]=1;
a[1]=1;
a[2]=2;
if(target<b && target>0){
return a[target];
}
for(int i=3;i<=target;i++){
a[i]=2*a[i-1];
}
return a[target];
}
//数学推导法:
/**
根据f(1)=1和f(n)=2∗f(n−1),我们最终可以得到,f(n)=2^(n−1)。
结论也符合逻辑大师的结论。
*/
public int JumpFloorII_withMath(int target) {
return 1<<(target-1);
}