声明:
作者不是什么大佬,只是想写写算法,提高一下自己的内功。所以代码可能会非常凌乱,(大佬们就当个笑话看就可以了),但我会认真注释。
最后如果有路过的大佬,希望可以留下你们的建议和看法,谢谢!
70. 爬楼梯
一、原题链接
二、题目介绍
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:
给定n是一个正整数
三、测试用例
1.示例
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1 阶 + 1 阶 + 1 阶
1 阶 + 2 阶
2 阶 + 1 阶
四、思路解析
这道题算是比较简单的动态规划的题。如果不知道什么是动态规划,可以到这个知乎回答上瞅一眼。什么是动态规划
而且这道台阶问题其实和凑钱问题几乎一样,如果改成最少需要几步到达楼顶,不论的题的难度,解法上也是完全一致。
- 首先我们先假设现在走到了5
- 那么5前有两种走法从4走一步与从3走两步
- 而4和3 也有有不同的方式走上来,根据第二步逻辑持续递归
- 最后将每条分支深入到0,其中每一条从0到5的支路就是一条路径
那么第i个结点的路径怎么算,我们可以人任取结点,发现其实就是左右结点的路径相加。最终我们可以列出方程dp(i) =dp(i-1)+dp(i-2)且i>=0
当然后面的且条件我们可以通过边界if加以规定
五、代码
优点:自上而下,容易结合上述图解进行学习
缺点:递归与重复操作,导致耗时太长,甚至会导致算法无法通过
// 递归算法
public int down(int n){
// 遍历到0的时候说明已经形成了一条路径了,返回 1
if(n==0){
return 1;
}else if(n>0) {
// 一般状态的递归调用 也是dp算法的体现dp(n) = dp(n-1)+dp(n-2)
return down(n-1)+down(n-2);
}else {
// 其他情况直接返回0
return 0;
}
}
public int climbStairs(int n) {
// 如果是0 直接就是0了不用走了
if(n==0){
return 0;
}
// 开始递归计算
int sum = down(n);
return sum;
}
核心还是:dp(i)=dp(i-1)+dp(i-2),我们可以看作成类似斐波那契数列来做
优点:完全解决了上述的操作,时间大大缩短
缺点:根据图解需要把顶层递归转化位底层循环,如果不熟练的话很有可能会写不出来
public int climbStairs(int n) {
// n为0直接返回0
if (n == 0) {
return 0;
}
// n == 1 直接一种
else if (n == 1) {
return 1;
}
// n == 2 固定两种
else if(n==2){
return 2;
}else {
//有了dp(1)和dp(2)的铺垫,就可以当作斐波那契数列计算
//上一层的最优 dp(i-1)
int last = 2;
//上上一层的最优 dp(i-2)
int last_last = 1;
// 循环操作
for (int i = 3; i <= n; i++) {
int temp = last;
// dp方程的体现
last = last_last+last;
last_last = temp;
}
// 返回
return last;
}
}