题目描述
假设你正在爬楼梯。需要 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
时就会因时间过长无法通过测试。分析其原因,乃是该问题存在重叠子问题特性。与此同时,注意到该问题具备最优子结构特性,因此可以考虑使用动态规划进行优化。显然,爬上第n
阶楼梯的方法数是爬上n-1
阶楼梯的方法数加上爬上n-2
阶楼梯的方法数的和。
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];
}
};
时间复杂度与空间复杂度都为
然而,我们注意到规模为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;
}
};
此时空间复杂度被优化为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异