题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 3
输出:3
题解
看到该题目描述,最直观的想法是借助递归不断减小问题规模,参考代码如下:
class Solution {
public:
int climbStairs(int n) {
int count = 0;
dfs(n, n, count);
return count;
}
void dfs(int n, int now, int& count)
{
if(now == 0)
{
count++;
return;
}
if(now - 2 >= 0)
{
dfs(n, now - 2, count);
dfs(n, now - 1, count);
}
else if(now >= 1)
dfs(n, now - 1, count);
}
};
该方法已经包含了最朴素的分支,但是在n=44
时就会因时间过长无法通过测试。分析其原因,乃是该问题存在重叠子问题特性,同时也注意到该问题也具备最优子结构特性,因此可以考虑使用动态规划进行优化。
class Solution {
public:
vector<int> stairs = vector<int>(46, 0);
int climbStairs(int n){
stairs[1] = 1;
stairs[2] = 2;
for(int i=3;i<=n;i++){
stairs[i] = stairs[i-1]+stairs[i-2];
}
return stairs[n];
}
};
时间复杂度与空间复杂度都为\(O(n)\)。
然而,我们注意到规模为n
时只会用到规模为n-1
和n-2
的子问题的解,因此可以使用滚动数组进行优化,即
class Solution {
public:
int climbStairs(int n) {
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
};
此时空间复杂度被优化为\(O(1)\)。
标签:count,爬楼梯,int,复杂度,dfs,70,now From: https://www.cnblogs.com/parallel-138/p/17133664.html