爬楼梯
753 字
4 分钟
爬楼梯
- 难度:简单
- 标签:动态规划、数学
动态规划(Dynamic Programming)入门
Tip
什么是动态规划? 动态规划(DP)的核心在于将一个复杂的问题分解成若干个重叠的子问题,并将子问题的解存储起来,避免重复计算。它的本质是:分治 + 记忆化 = 动态规划。
动态规划的四个基本步骤
- 定义状态:
dp[i]存放的是什么?(例如:到达第i阶的方法数)。 - 转移方程:大问题如何由小问题推导出来?(例如:
dp[i] = dp[i-1] + dp[i-2])。 - 确定边界:最简单的情况(初始值)是什么?(例如:
dp[1] = 1, dp[2] = 2)。 - 计算顺序:自顶向下(递归+记忆化)或自底向上(循环迭代)。
题目描述
Note
原题说明:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例
- 输入:
n = 2-> 输出:2(1+1 或 2) - 输入:
n = 3-> 输出:3(1+1+1 或 1+2 或 2+1)
方案:滚动数组优化(动态规划)
核心思路:
要到达第 n 阶,最后一步只有两种可能:
- 从第
n-1阶跨 1 步上来(共有f(n-1)种方法)。 - 从第
n-2阶跨 2 步上来(共有f(n-2)种方法)。 因此,状态转移方程为:。这正是著名的斐波那契数列。
源码实现
class Solution {public: int climbStairs(int n) { if (n <= 1) return 1;
// 使用三个变量进行滚动更新,将空间复杂度降至 O(1) int a = 1; // f(n-2) int b = 1; // f(n-1) int c = 0; // f(n)
for (int i = 2; i <= n; ++i) { c = a + b; // 当前阶 = 前两阶之和 a = b; // 窗口向右滚动 b = c; } return b; }};复杂度分析
- 时间复杂度:。我们只需进行一次线性循环即可计算出结果。
- 空间复杂度:。我们使用了“滚动数组”技巧,只保存了前两个状态,而非维护一整个
vector<int> dp(n)。
常见问答
Q:为什么不用纯递归?
A:纯递归会产生大量的重复计算(如计算 f(5) 需要 f(4) 和 f(3),计算 f(4) 又需要 f(3)…)。这会导致时间复杂度爆炸(指数级 ),当 时基本会超时。
Q:如果每次可以爬 1、2、3 步呢? A:同理推导出方程 ,只需要增加一个初始化状态即可。
总结
- 状态转移是核心:找到“最后一步”的逻辑,就能写出方程。
- 空间优化:当当前状态只依赖于前几个固定状态时,用变量替代数组是极佳的性能优化。
Important
爬楼梯是动态规划最经典的入门题。理解了它的分治思想,你就跨过了学习高级算法的第一道门槛!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2025-10-18,距今已过 193 天
部分内容可能已过时
相关文章 智能推荐
1
x 的平方根
算法 力扣第69题:实现 sqrt(x)。深入理解二分查找在数值逼近中的应用,以及避免溢出的数学处理技巧。
2
加一
算法 力扣第66题:加一。处理大整数数组的进位逻辑,从逐位检查到首位插入的技巧分析。
3
罗马数字转整数
算法 力扣第13题:罗马数字转整数。探索如何处理特殊减法规则,并对比函数映射与哈希表两种实现方式。
4
回文数
算法 力扣第9题:回文数的判断。从暴力取余到“反转一半”的思路演进,以及字符串双指针解法。
5
删除排序链表中的重复元素
算法 力扣第83题:删除排序链表中的重复元素。深入理解链表指针操作,掌握“跳过”重复节点的优雅技巧。
随机文章 随机推荐