【刷题第18天】 爬楼梯的最少成本

158 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

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

二、思路分析:

这是一个明显的动态规划问题,在每个索引处有两种情况可以过来,即迈一步楼梯和迈两步楼梯,而且第 i 层楼梯处的最少成本不会影响后续,因此没有后效性,所以我们可以使用动态规划。

假设共有n阶楼梯,我们创建长度为 n+1 的 dp数组,其中 dp[i] 存储到达阶梯i的最小成本。

初始化 dp[0] = dp[1] = 0 即第一阶和第零阶楼梯都为 0。

然后后续遍历,对于第 i 阶楼梯,共有两种方案可以过来

  • 从第 i-2 阶楼梯麦两阶楼梯,dp[i-2]+cost[i-2]
  • 从第 i-1 阶楼梯麦一阶楼梯,dp[i-1]+cost[i-1]
  • 取两者的最小值为当前楼梯的最小成本

依次遍历,最终 dp[n] 即为到达楼梯顶部的最小花费。

三、AC 代码:

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

四、总结:

这个题目算动态规划中比较简单的题目,我们只需注意边界条件的处理即可。我们添加一个第零阶让转移方程更完善。