LeetCode70 爬楼梯
题目描述
假设你正在爬楼梯,有n个台阶,每次你可以跨1个或2个台阶。你有多少种不同的方法可以到达屋顶呢?
注意:n是一个正整数
示例
输入:2
输出:2
解释:只有两个台阶,你可以选择1阶1阶的爬,或者一次爬两阶,因此共有两种方法。
输入:3
输出:3
解释:
- 1阶 + 1阶 + 1阶
- 1阶 + 2阶
- 2阶 + 1阶
共有三种方法
题目解析
题目问的是我们一共有多少种爬楼梯的方式,即每次都可以选择爬一阶和爬两阶,将这两个分支的所有可能情况加起来的就是我们要的答案了。
我们可以发现,每当我们走一次,都相当于重复相同的问题,但是此时n的值在变小。对于相同问题,问题规模在变小的情况,我们可以使用动态规划思想来解答。即大规模的问题由小规模问题的解构成,其方程如下:
dp[i] = dp[i - 1] + dp[i - 2];
题解
1.递归式动态规划
这道题是可以使用递归的方式求解,代码很简单,如下:
public int climbStairs(int n) {
if (n < 0) {
// n小于0的话接下去就没有可以走的了,返回0
return 0;
}
if (n == 1) {
//n等于1接下去就只有一种方式可以走,直接返回1
return 1;
}
if (n == 0) {
//n等于0表示由更大规模到更小规模的情况下只有这一种情况可以走,例如只有两个台阶时2 - 2 = 0,这时只有这种情况,
//下面没有可以再分的情况了,1 - 1 = 0也是类似的情况 所以这里应该返回1,而不是返回0
return 1;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
但是,这种方法很多时候提交会超时,试了一下,超时了。
2.递推式动态规划
相比于递归的方法,递推式方程的方法用的更多,而且一般都一个循环(O(n)的时间复杂度)即可解决问题。而递归式的方法主要是找到那个递归方程,这道题的递推方程式:dp[i] = dp[i - 1] + dp[i - 2]; 其实形式上和递归的方式是类似的。
java代码如下
public int climbStairs(int n) {
if (n == 1) {
return 1;
}
int[] dp = new int[n + 1];
dp[1] = 1; // 一个楼梯时有一种走法
dp[2] = 2; //一个楼梯时有两种走法
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; //由更小规模构成
}
return dp[n];
}
程序执行结果: