导读
这次带来的是动态规划经典问题:爬楼梯,动态规划只要找到两个东西就可以解了,
- 状态
dp[i]
- 状态转移方程
题目难度:简单Easy
题目描述:
有 N 阶楼梯,每次可以上一阶或者两阶,求有多少种上楼梯的方法。
- 状态
dp[i]
:表示走到第 i i i阶楼梯一共有多少种方法; - 状态转移方程:因为每次只能上一到两阶楼梯,故上到第i阶楼梯的方法数等于上到第
i
−
1
i-1
i−1阶的方法数和上到第
i
−
2
i-2
i−2阶的方法数之和,即
d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i]=dp[i-1]+dp[i-2] dp[i]=dp[i−1]+dp[i−2]
代码如下:
class Solution:
def climbStairs(self, n: int) -> int:
if (n <= 2):
return n
dp = [0] * (n + 1) # 因为dp[i]即代表上到第i阶的方法数,故跳过dp[0],往后多申请一个空间,dp[n]代表上到第N阶的方法数
dp[1], dp[2] = 1, 2 # 赋初值:上一阶是1种方法,上两阶是2种方法
for i in range(3, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
考虑到dp[i]只与dp[i - 1]和dp[i - 2]有关,因此可以只用两个变量来存储dp[i - 1]和dp[i - 2],使得原来的O(N)空间复杂度优化为O(1) 复杂度。即不需要申请n+1个空间,只申请两个变量cur和pre即可。
class Solution {
public int climbStairs(int n) {
if (n <= 2) {
return n;
}
int smaller = 1, bigger = 2; // smaller相当于dp[i-2],bigger相当于dp[i-1]
for (int i = 2; i < n; i++) {
int temp = smaller + bigger; // 得到中间值1+2=3
smaller = bigger; // 先把bigger给smaller,即先让smaller=2
bigger = temp; // 再把temp赋给bigger,即再让bigger=3
}
return bigger;
}
}