LeetCode第764题:使用最小花费爬楼梯

147 阅读2分钟

这是我参与更文挑战的第13天,活动详情查看: 更文挑战

题干

数组的每个下标作为一个阶梯,第 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 。

思路:动态规划

此题有很多暗含条件,比如,我们初始时可以随意选择在第一个位置或是第二个位置开始。并且我们可以

1. 找到dp[i]数组以及下标的含义:到i台阶所花费的最小体力(暗含求和操作)

2. 总结递推公式:

我们现在就使用[10,15,20]来看。首先我们的初始值一定是dp[0]=10,dp[1]=15。因为这里我们是我们的起点。我们只能二选一。当然这也决定了我们的dp[i]的值。dp[i]的值就是它前面的两个值取出一个最小值然后与当前体力值进行相加,这一步其实也是暗含我们求体力值的和,方便下一次比较。

注:如果取i-1说明我们跳一个,如果取i-2则说明我们跳两个。

得出递推公式:

dp[i]=min(dp[i-1],dp[i-2])+cost[i]

3. dp数组如何初始化:初始化F(0) = 0,F(1) = 1

4.确定遍历的顺序:我们后一个的值总是依赖当前值,所以我们遍历顺序是从前向后

5.举例推导一下递推公式

微信图片_20210615192610.jpg 代码实现:

执行用时:112 ms, 在所有 JavaScript 提交中击败了11.27%的用户

内存消耗:42 MB, 在所有 JavaScript 提交中击败了5.06%的用户

 var minCostClimbingStairs = function (cost) {
    let dp = [];
    dp[0] = cost[0]
    dp[1] = cost[1]
    let allLength = cost.length
    for (let i = 2; i < allLength; i++) {
      dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i]
    }
    console.log(dp)
    return Math.min(dp[allLength - 1], dp[allLength - 2])
  };

注意:为什么我们要返回dp[i-1]和dp[i-2]的最小值,因为我们这两个位置都是可以跳上台阶,所以我们直接选择两者最小值。