引言
力扣题目【爬楼梯】描述 -> 传送门
所用语言:Java
执行用时 0 ms,内存消耗 35.2 MB
时间复杂度 O(n) ,空间复杂度 O(1)
正文
和斐波那契数列一样的解法
这道题目,一看就很熟悉,和斐波那契数列异曲同工,可以使用递归,当然也可以使用动态规划来解
关于动态规划,我也还在学习中,所以我解这道题目时,习惯是:先使用递归解决 -> 然后优化成使用动态规划来解决
递归解法
递归解法的详细思路我就不先在这里说,先上代码:
public int climbStairs(int n) {
if (n == -1) {
return 0;
}
if (n == 0) {
return 1;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
需要说明的是:用这个递归解法时,当 n = 44 时,运行超时了,并不理想
动态规划
想要写出动态规划解法,就要解决两件事情:
- ① 找出重叠子问题
- ② 写出状态转移方程
重叠子问题
首先找出这道题的重叠子问题,先使用递归的思想画出解这道题的一个图示:
- 爬3阶的楼梯时:
- 以爬4阶的楼梯时:
在这里,我实际上是把爬楼梯问题转为了下楼梯问题,本质上都是一样,只是为了更直观地说明而做了这样的转化
结合这两个图示,我们可以直观地看出,下4阶楼梯的解法中包含了下3阶楼梯的解法。下4阶楼梯的方案①包含下3阶楼梯的方案①;下4阶楼梯的方案③包含下3阶楼梯的方案②;下4阶楼梯的方案④包含下3阶楼梯的方案③。这就是这道题的重叠子问题
状态转移方程
然后,我们可以直接写出状态转移方程:
动态规划解法
所以,用动态规划思想得到的答案如下:
public int climbStairs(int n) {
int n1 = 1;
int n2 = 0;
int result = 0;
for (int i = 1; i <= n; i++) {
result = n1 + n2;
n2 = n1;
n1 = result;
}
return result;
}
最后
最近时间有点紧,所以解题过程我没有写的很详细,所以,如果看了上文还是不能理解的话,可以在评论区直接提问