LeetCode做题笔记 - 70 - 爬楼梯(简单)

题目:爬楼梯(难度:简单)

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

Example 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 2:

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

思路

爬到第N层有2种情况,一是从第N-1层跨一步到第N层,二是从第N-2层跨两步到第N层。所以到第N层的方法数等于到第N-1层和到第N-2层方法数之和。我们用f(N)表示到第N层的方法数,则有 f(N) = f(N-1) + f(N-2)。是不是很像斐波那契数列。
首先想到用递归,但是考虑到复杂度问题,用一个带unordered_map记录已经算得的结果,避免重复运算,时间和空间复杂度都是O(N)
第二种写法更简单,把f(N)看成一个数组f的第N个元素,那么从0循环到N即可算出f(N),时间和空间复杂度都是O(N)
虽然理论上两种方法的时间和空间复杂度的数量级一样,但是第二种更省时间和空间,因为递归涉及频繁函数调用消耗时间,而且unordered_map的搜索只是平均为常数时间,最差情况仍与大小有关。

代码

递归

class Solution {
public:
    int climbStairs(int n) {
        // 递归
        if (n == 1) return 1;
        if (n == 2) return 2;
        if (record.find(n) != record.end()) return record[n]; // 去记录中找结果,避免重复运算
        int ways = climbStairs(n-1)+climbStairs(n-2); // 递归调用
        record[n] = ways; // 记录结果
        return ways;
    }
    
    unordered_map<int, int> record; // 记录算过的结果,避免重复运算
};

数组(推荐)

class Solution {
public:
    int climbStairs(int n) {
        int size = n < 2 ? 3 : n+1; // 确定数组的大小,长度不能小于3
        int *sum = new int [size];
        
        sum[0] = 0; // 初始化最开头的元素
        sum[1] = 1;
        sum[2] = 2;
        
        for(int i = 3; i <= n; i++)
            sum[i] = sum[i - 1] + sum[i - 2]; // 根据规则计算
        
        return sum[n];
    }
};
posted @   星夜之夏  阅读(151)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示