[剑指offer]跳台阶问题&动态规划求解
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
示例1
输入
1
返回值
1
示例2
输入
4
返回值
5
递归的方式求解:
由于它可以跳1级台阶或者2级台阶,所以它上一步必定在第n-1,或者第n-2级台阶,也就是说它跳上n级台阶的跳法数是跳上n-1和跳上n-2级台阶的跳法数之和。
public class Solution {
public int JumpFloor(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
return JumpFloor(n - 1) + JumpFloor(n - 2);
}
}
动态规划的思想:
用于求最优化问题,将问题分为多个字问题分别求最优值,再求整个问题的最优值。解决问题的方法类似于分治法,而与分治法不同的是,动态规划问题子问题的最优解不是互相独立的,可以通过
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重
复计算,节省时间。
动态规划的问题分析:
青蛙要跳到第三层,有两种情况:
1.先跳到第一层,剩下两层有两种跳法
2.先跳到第二层,剩下一层有一种跳法
把问题推广到n层:
1.先调到1层,剩下n-1层设有pre1种跳法
2.先调到2层,剩下n-2层设有pre2种跳法
同时可以发现第 n 阶的解法,只要用到 n - 1 和 n - 2 阶是多少,其他的不用考虑,因此用两个变量临时存下来即可
dp(i) = dp(i-2) + dp(i-1)
public class Solution {
public int JumpFloor(int target) {
if(target <= 2){
return target;
}
int pre2 = 1, pre1 = 2;
for (int i = 3; i <= target; i++){
int cur = pre2 + pre1;
pre2 = pre1;
pre1 = cur;
}
return pre1;
}
}
温故而知新