使用最小花费爬楼梯

62 阅读2分钟

题目链接: 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];
	}
}