70. 爬楼梯 - 力扣(LeetCode)
假设你正在爬楼梯。需要 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阶楼顶,后续解决!!!尽情期待 ~(挖个坑,后续填坑!)