当前位置: 首页 > news >正文

【算法】动态规划 70: 爬楼梯

在这里插入图片描述

【70】爬楼梯

假设你正在爬楼梯。需要 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 <= n <= 45

分析

我们记 dp[i] 为到达第 i 阶的方法数。因为每次只能爬 1 阶或 2 阶:

  • 当你到达第 i 阶时,上一跳要么是从 i − 1 阶跨 1 阶,要么是从 i − 2 阶跨 2 阶。

  • 因此状态转移方程为

    dp[i] = dp[i-1] + dp[i-2]  
    
  • 边界条件:

    • dp[1] = 1 (只有一步跨 1)
    • dp[2] = 2 (1+1 或 2)

由于题目给出 1 ≤ n ≤ 45,我们可以用 O(n) 的时间和 O(1) 的额外空间完成计算。


方法一:滚动数组(最优空间)

只需要用两个变量维护前两项即可。

// C++ 实现
class Solution {
public:int climbStairs(int n) {if (n <= 2) return n;int prev2 = 1;    // dp[1]int prev1 = 2;    // dp[2]int cur = 0;for (int i = 3; i <= n; ++i) {cur = prev1 + prev2;  // dp[i] = dp[i-1] + dp[i-2]prev2 = prev1;prev1 = cur;}return cur;}
};
# Python 实现
class Solution:def climbStairs(self, n: int) -> int:if n <= 2:return nprev2, prev1 = 1, 2  # 分别对应 dp[1], dp[2]for _ in range(3, n+1):prev2, prev1 = prev1, prev1 + prev2return prev1
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

方法二:递归 + 备忘录(Memoization)

虽然递归写法更直观,但没有优化的话会指数级爆炸。我们可以加一个数组或哈希表缓存已经计算过的结果。

// C++ 实现:递归 + 备忘录
class Solution {vector<int> memo;
public:Solution(int n) : memo(n+1, -1) {}int climbStairs(int n) {memo[0] = 1;  // 为了递归基线,定义到 0 阶有 1 种“空走”方法memo[1] = 1;return helper(n);}int helper(int i) {if (memo[i] != -1) return memo[i];// 从 i-1 阶跨 1,或 i-2 阶跨 2memo[i] = helper(i-1) + helper(i-2);return memo[i];}
};
# Python 实现:递归 + 备忘录
class Solution:def __init__(self):self.memo = {}def climbStairs(self, n: int) -> int:return self._dfs(n)def _dfs(self, i: int) -> int:if i <= 2:return iif i not in self.memo:self.memo[i] = self._dfs(i-1) + self._dfs(i-2)return self.memo[i]
  • 时间复杂度:O(n) (每个状态最多计算一次)
  • 空间复杂度:O(n) (递归栈深度 + 备忘录)

举例验证
  • 当 n=2 时:
    dp[1]=1, dp[2]=2 ⇒ 返回 2

  • 当 n=3 时:
    dp[1]=1, dp[2]=2, dp[3]=dp[2]+dp[1]=3 ⇒ 返回 3

以上两种方法都能在常数级空间或线性空间内,快速算出答案。

http://www.lqws.cn/news/586909.html

相关文章:

  • ue xr 系统
  • 飞算 JavaAI 深度实战:从老项目重构到全栈开发的降本增效密码
  • 【Spring AI】 1接入 Ollama实践
  • 周赛98补题
  • C/C++ 使用rapidjson库 操作Json格式文件(创建、插入、解析、修改、删除)
  • 【数论 构造】 P11036 【MX-X3-T3】「RiOI-4」GCD 与 LCM 问题|普及+
  • 高效读取文件中指定行段的两种方法
  • mysql运维语句
  • C++ Vector的使用(下)
  • Qt Hello World 程序
  • ES6从入门到精通:箭头函数
  • C++ Vector的使用(上)
  • Linux基础环境开发工具apt、vim和gcc/g++
  • Excel 中拖动公式时,如何让引用的单元格“固定”或“变动”?
  • Vue3——项目配置eslint+prettier
  • Instruct-GPT奖励模型的损失函数与反向传播机制解析
  • [15-2] 读写内部FLASH读取芯片ID 江协科技学习笔记(20个知识点)
  • 【C++指南】C++ list容器完全解读(三):list迭代器的实现与优化
  • 如何查看服务器的运行日志?
  • 关于Spring的那点事(1)
  • 【CSS】Grid 布局基础知识及实例展示
  • 内网ubuntu系统安装mysql
  • 《如何在 Spring 中实现 MQ 消息的自动重连:监听与发送双通道策略》
  • 算法题练习
  • 前端Vue面试八股常考题(一)
  • 【STM32HAL-第1讲 基础篇-单片机简介】
  • Redis Lua 调试器(LDB)完全指南
  • 具身智能的仿真技术(具身智能入门三)
  • 用Python采集CBC新闻:如何借助青果网络海外代理IP构建稳定采集方案
  • datax-web报错:连接数据库失败. 请检查您的 账号、密码、数据库名称、IP、Port或者向 DBA 寻求帮助(注意网络环境)