Easy
题目描述
给你一个整数数组 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
解题思路
这是一个经典的动态规划问题。我们需要计算到达楼梯顶部的最小花费。
核心思路:
- 定义
dp[i]表示从第i个台阶出发到达楼梯顶部的最小花费 - 楼梯顶部可以看作是下标
n(数组长度)的位置 - 状态转移方程:
dp[i] = cost[i] + min(dp[i+1], dp[i+2])- 从第
i个台阶出发,支付cost[i]后,可以到达i+1或i+2位置
- 从第
- 边界条件:
dp[n] = dp[n+1] = 0(已经到达顶部,无需花费)
解法优化:
- 方法一:使用 dp 数组从后往前计算
- 方法二:空间优化,只用两个变量存储后两个状态(推荐)
由于每次只需要用到后面两个状态,我们可以用两个变量来优化空间复杂度。从后往前遍历,不断更新这两个变量即可。
最终答案是 min(dp[0], dp[1]),因为我们可以从第 0 或第 1 个台阶开始。
代码实现
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
int next1 = 0, next2 = 0; // dp[i+1], dp[i+2]
for (int i = n - 1; i >= 0; i--) {
int current = cost[i] + min(next1, next2);
next2 = next1;
next1 = current;
}
return min(next1, next2);
}
};
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
next1, next2 = 0, 0 # dp[i+1], dp[i+2]
for i in range(n - 1, -1, -1):
current = cost[i] + min(next1, next2)
next2 = next1
next1 = current
return min(next1, next2)
public class Solution {
public int MinCostClimbingStairs(int[] cost) {
int n = cost.Length;
int next1 = 0, next2 = 0; // dp[i+1], dp[i+2]
for (int i = n - 1; i >= 0; i--) {
int current = cost[i] + Math.Min(next1, next2);
next2 = next1;
next1 = current;
}
return Math.Min(next1, next2);
}
}
var minCostClimbingStairs = function(cost) {
const n = cost.length;
let next1 = 0, next2 = 0; // dp[i+1], dp[i+2]
for (let i = n - 1; i >= 0; i--) {
const current = cost[i] + Math.min(next1, next2);
next2 = next1;
next1 = current;
}
return Math.min(next1, next2);
};
复杂度分析
| 复杂度类型 | 数组DP解法 | 空间优化解法(推荐) |
|---|---|---|
| 时间复杂度 | O(n) | O(n) |
| 空间复杂度 | O(n) | O(1) |