posts - 35,comments - 0,views - 3126

70.爬楼梯

题目描述

假设你正在爬楼梯。需要 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];
    }
};

时间复杂度与空间复杂度都为O(n)
然而,我们注意到规模为n时只会用到规模为n-1n-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)

posted on   sc01  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示