LeetCode 题解工作台
使用最小花费爬楼梯
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 示例 1: 输入: cost = [10, 15 ,2…
2
题型
7
代码语言
3
相关题
当前训练重点
简单 · 状态·转移·动态规划
答案摘要
我们设计一个函数 ,表示从第 个阶梯开始爬楼梯所需要的最小花费。那么答案为 $\min(\textit{dfs}(0), \textit{dfs}(1))$。 函数 的执行过程如下:
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20] 输出:15 解释:你将从下标为 1 的台阶开始。 - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 总花费为 15 。
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1] 输出:6 解释:你将从下标为 0 的台阶开始。 - 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。 - 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。 - 支付 1 ,向上爬一个台阶,到达楼梯顶部。 总花费为 6 。
提示:
2 <= cost.length <= 10000 <= cost[i] <= 999
解题思路
方法一:记忆化搜索
我们设计一个函数 ,表示从第 个阶梯开始爬楼梯所需要的最小花费。那么答案为 。
函数 的执行过程如下:
- 如果 ,表示当前位置已经超过了楼梯顶部,不需要再爬楼梯,返回 ;
- 否则,我们可以选择爬 级楼梯,花费为 ,然后递归调用 ;也可以选择爬 级楼梯,花费为 ,然后递归调用 ;
- 返回两种方案中的最小花费。
为了避免重复计算,我们使用记忆化搜索的方法,将已经计算过的结果保存在数组或哈希表中。
时间复杂度 ,空间复杂度 。其中 是数组 的长度。
Python3
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
@cache
def dfs(i: int) -> int:
if i >= len(cost):
return 0
return cost[i] + min(dfs(i + 1), dfs(i + 2))
return min(dfs(0), dfs(1))
Java
class Solution {
private Integer[] f;
private int[] cost;
public int minCostClimbingStairs(int[] cost) {
this.cost = cost;
f = new Integer[cost.length];
return Math.min(dfs(0), dfs(1));
}
private int dfs(int i) {
if (i >= cost.length) {
return 0;
}
if (f[i] == null) {
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
}
return f[i];
}
}
C++
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
int f[n];
memset(f, -1, sizeof(f));
auto dfs = [&](this auto&& dfs, int i) -> int {
if (i >= n) {
return 0;
}
if (f[i] < 0) {
f[i] = cost[i] + min(dfs(i + 1), dfs(i + 2));
}
return f[i];
};
return min(dfs(0), dfs(1));
}
};
Go
func minCostClimbingStairs(cost []int) int {
n := len(cost)
f := make([]int, n)
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(i int) int {
if i >= n {
return 0
}
if f[i] < 0 {
f[i] = cost[i] + min(dfs(i+1), dfs(i+2))
}
return f[i]
}
return min(dfs(0), dfs(1))
}
TypeScript
function minCostClimbingStairs(cost: number[]): number {
const n = cost.length;
const f: number[] = Array(n).fill(-1);
const dfs = (i: number): number => {
if (i >= n) {
return 0;
}
if (f[i] < 0) {
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
}
return f[i];
};
return Math.min(dfs(0), dfs(1));
}
Rust
impl Solution {
pub fn min_cost_climbing_stairs(cost: Vec<i32>) -> i32 {
let n = cost.len();
let mut f = vec![-1; n];
fn dfs(i: usize, cost: &Vec<i32>, f: &mut Vec<i32>, n: usize) -> i32 {
if i >= n {
return 0;
}
if f[i] < 0 {
let next1 = dfs(i + 1, cost, f, n);
let next2 = dfs(i + 2, cost, f, n);
f[i] = cost[i] + next1.min(next2);
}
f[i]
}
dfs(0, &cost, &mut f, n).min(dfs(1, &cost, &mut f, n))
}
}
JavaScript
function minCostClimbingStairs(cost) {
const n = cost.length;
const f = Array(n).fill(-1);
const dfs = i => {
if (i >= n) {
return 0;
}
if (f[i] < 0) {
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
}
return f[i];
};
return Math.min(dfs(0), dfs(1));
}
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(n) because we iterate through each step once, and space complexity can be O(n) with the full DP array or optimized to O(1) by storing only the last two states. This trade-off is specific to state transition dynamic programming patterns where only previous states affect the current computation. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Asks how you handle both starting indices 0 and 1 to ensure minimal cost.
- question_mark
Questions about optimizing space while preserving correct state transitions.
- question_mark
Wants explanation of why dp[i] = cost[i] + min(dp[i-1], dp[i-2]) captures all possible paths efficiently.
常见陷阱
外企场景- error
Confusing array indices and overstepping boundaries when computing dp[i].
- error
Failing to account for starting from index 1, which may yield a lower total cost.
- error
Attempting to reconstruct the path instead of just computing minimum cost, which can overcomplicate the solution.
进阶变体
外企场景- arrow_right_alt
Climbing stairs with variable maximum step size per stair.
- arrow_right_alt
Min cost climbing stairs with constraints on consecutive step selections.
- arrow_right_alt
Counting the number of distinct minimum-cost paths to reach the top.