题目链接: leetcode.cn/problems/Gz…
题目描述:
数组的每个下标作为一个阶梯,第 i
个阶梯对应着一个非负数的体力花费值 cost[i]
(下标从 0
开始)。
每当爬上一个阶梯都要花费对应的体力值,一旦支付了相应的体力值,就可以选择向上爬一个阶梯或者爬两个阶梯。
请找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。
示例 1:
输入: cost = [10, 15, 20] 输出: 15 解释: 最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。
示例 2:
输入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 输出: 6 解释: 最低花费方式是从 cost[0] 开始,逐个经过那些 1 ,跳过 cost[3] ,一共花费 6 。
提示:
2 <= cost.length <= 1000
0 <= cost[i] <= 999
题目解析
这题使用动态规划来解
dp[i]:走到 i 个台阶需要的累计花费
花费 cost[i]的费用你可以选择跳一步或者两步
所以 dp[i] 可以是 dp[i - 1] 或者 dp[i - 2]跳过来的
dp[i] = dp[i - 1] + cost[i - 1]这个是花费 cost[i - 1]然后往前跳一步,再加上之前的花费 dp[i - 1],得到 dp[i]
dp[i] = dp[i - 2] + cost[i - 2]这个是花费 cost[i- 2] 往前跳两步,在加上之前花费的 dp[i - 2],得到 dp[i]
但是我们需要的是最小的花费,所以使用 Math.min 进行判断,是跳一步花费的少还是两步花费的少
这题还有一个细节,很重要,就是到底哪是终点?是 cost[cost.length - 1]吗?其实不是,而是这个数组的终点外的地方
抽象表示就是 cost[cost.length](不存在)。所以我们在建数组的时候,需要多建立一个下标。
代码
public class Solution {
public static int minCostClimbingStairs(int[] cost) {
int[] dp = new int[cost.length + 1];
for (int i = 2; i < dp.length; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[dp.length - 1];
}
}