一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶(n为正整数)总共有多少种跳法。
数据范围:
进阶:空间复杂度
, 时间复杂度 )
进阶:空间复杂度
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number int整型
* @return int整型
*/
public int jumpFloorII (int number) {
int[] dp = new int[number+1];
dp[0] = 1;
for(int i=1;i<=number;i++){
for(int j=i-1;j>=0;j--){
dp[i] += dp[j];
}
}
return dp[number];
}
} import java.util.*;
public class Solution {
public int jumpFloorII(int target) {
if(target == 1) return 1;
if(target == 2) return 2;
int[] dp = new int[target + 1];
Arrays.fill(dp,1);
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i < target + 1; i ++) {
for (int j = 1; j < i; j ++) {
dp[i] = dp[i] + dp[j];
}
}
return dp[target];
}
} //每集台阶都有踩与不踩两种情况,n级台阶就是2的n次方,但是最后一个台阶是必须踩的,所以n-1个台阶需要踩,即2的n-1次方,即1<<(n-1)
public class Solution {
public int jumpFloorII(int target) {
if(target == 1)
return 1;
int[] arr = new int[target]; //状态:跳上n节台阶的方法个数为arr[n-1]
arr[0] = 1; //初始化
for(int i = 1;i<target;i++){
arr[i] = 2*arr[i-1];//状态转移方程
}
return arr[target-1]; //返回值
}
} public class Solution {
public int jumpFloorII(int target) {
if(target == 0) return 0;
if(target == 1) return 1;
if(target == 2) return 2;
int[] dp = new int[target];
dp[0] = 1;
dp[1] = 2;
int j = 1;
for(int i = 2;i < target;i++){
dp[i] = 1; //跳n级的时候
while(j < target && i - j >= 0){
dp[i] += dp[i - j];
j++;
}
j = 1;
}
return dp[target - 1];
}
} import java.util.*;
public class Solution {
public int jumpFloorII(int target) {
if (target <= 2) {
return target;
}
// dp[i]代表到i+1台阶有多少种跳法
int[] dp = new int[target];
dp[0] = 1;
dp[1] = 2;
for (int i = 2; i < target; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[i - j];
}
// 必须要加1,代表一下跳到i层
dp[i] += 1;
}
//System.out.println(Arrays.toString(dp));
return dp[dp.length - 1];
}
} public class Solution {
int n,cot=0;
public int jumpFloorII(int target) {
n=target; //传给全局变量,方便dfs中比对
dfs(0);
return cot;
}
private void dfs(int sum) {
if(sum>n) return; // 跳多了,碰壁返回
if(sum==n){ // 刚好跳中,新的情况所以要记录,然后也返回
cot++;
return;
}
for(int i=1;i<=n;i++){ //1~n每种跳法都尝试一遍
dfs(sum+i);
}
}
} public class Solution {
private int rst=0;
public int jumpFloorII(int target) {
for(int s=1;s<=target;s++)
dfs(target,s);
return rst;
}
public void dfs(int target,int diff){
int tmp=target-diff;
if(tmp==0)
rst++;
else if(tmp<0)
return;
else{
for(int i=1;i<=tmp;i++)
dfs(tmp,i);
}
}
} public int jumpFloorII(int target) {
return 1 << (target - 1);
} public class Solution {
public int jumpFloorII(int target) {
// 分析得到(1)式:f(n) = f(n-1) + f(n-2) +....+f(0)
// 统一减个1,得到(2)式:f(n-1) = f(n-2) + f(n-3) +......+f(0)
// (1)-(2)得到:f(n) = 2 f(n-1),以此为基础,构建代码:
if(target==0){
return 0;
}
// 根据表达式,只需要一个指针就可以了
int sum = 1;
for(int i=1;i<target;i++){
sum = 2 * sum;
}
return sum;
}
}
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
...
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:
| 1 ,(n=0 )
f(n) = | 1 ,(n=1 )
public class Solution { public int jumpFloorII(int target) { if (target <= 0) { return -1; } else if (target == 1) { return 1; } else { return 2 * jumpFloorII(target - 1); } } }