1. 题目:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
2. 我的代码:
class Solution: def climbStairs(self, n: int) -> int: if n == 1: return 1 if n == 2: return 2 # 初始化dp dp = [0] * (n + 1) # 起始 dp[1] = 1 dp[2] = 2 # 递推关系 + 向前递推 for i in range(3, n + 1): dp[i] = dp[i - 1] + dp[i - 2] return dp[n]
动态规划最重要最需要理清楚的点:
- dp数组及其下标的含义
- 递推公式
- dp数组初始化
- 遍历顺序
这里,我们的推理:
- dp下标表示的是第几个阶梯,dp元素代表的是到达该阶梯的方法的个数
- 递推公式,我们想一下,到达该阶梯的方法个数,等于到达前两个阶梯方法个数的和,因为倒数第二个阶梯只需要迈一步2格,或者倒数第一个阶梯只需要迈一步1格。因此,和斐波那契数列一致:dp[n] = dp[n - 1] + dp[n - 2]
- dp数组的初始化,由于要用到两个数组,所以,至少需要知道前两个阶梯的dp值,到达dp[1]可以迈一步1格,到达dp[2]可以迈一步2格或者迈两步1格,所以,dp[1] = 1,dp[2] = 2
- 遍历的话就从3遍历到n即可
(当然,这里也需要排除一下1和2的特殊情况,不然数组会越界)