假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶
示例 2:
输入:n = 3 输出:3 解释:有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶
思路:
动规五部曲
定义一个一维数组来记录不同楼层的状态
1.确定dp数组以及下标的含义
dp[i]:爬到第i层楼梯,有dp[i]种方法
2.确定递推公式
如何推出dp[i]呢?
从dp[i]的定义可以看出,dp[i]可以有两个方向推出。首先是dp[i-1],上i-1层楼梯,有dp[i-1]种方法,那么再一步跳一个台阶就是dp[i]了。还要dp[i-2],上i-2层楼梯,有dp[i-2]种方法,那么再一步跳两个台阶就是dp[i]了
也就是说可以求出dp[i],即dp[i] = dp[i-1] + dp[i-2]
3.dp数组初始化
dp[1]=1,dp[2]=2,从i = 3开始递推,这样才符合dp[i]的定义
4.确定遍历顺序
从递推公式dp[i] = dp[i-1] + dp[i-2];中可以看出,遍历顺序一定是从前向后遍历的
5.举例推导dp数组
i: 1 2 3 4 5
dp[i]: 1 2 3 5 8
- class Solution {
- public:
- // 动态规划 时间复杂度:O(n) 空间复杂度:O(n)
- int climbStairs(int n) {
- if(n<=1) return n;// 因为下面直接对dp[2] 操作了,防止空指针
- vector<int> dp(n+1);
- dp[1] = 1;
- dp[2] = 2;
- for(int i=3;i<=n;i++) { //注意i是从3开始的
- dp[i] = dp[i-1] + dp[i-2];
- }
- return dp[n];
- }
- }
- class Solution {
- public:
- // 版本二 优化空间复杂度为O(1)
- int climbStairs(int n) {
- if(n<=1) return n;// 因为下面直接对dp[2] 操作了,防止空指针
- int dp[3];
- dp[1] = 1;
- dp[2] = 2;
- for(int i=3;i<=n;i++) {
- int sum = dp[1] + dp[2];
- dp[1] = dp[2];
- dp[2] = sum;
- }
- return dp[2];
- }
- }
好问题:若一步一个台阶,两个台阶,三个台阶,直到 m 个台阶,有多少种方法爬到n阶楼顶,后续解决!!!尽情期待 ~(挖个坑,后续填坑!)
>>另一种动态规划的三个步骤划分,来自这个up主的视频,以下笔记来自该视频的总结:
[轻松掌握动态规划]1.爬楼梯_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1HY4y1Z7fs/?spm_id_from=333.999.0.0

