【力扣刷题】746. 使用最小花费爬楼梯

622 阅读2分钟

「这是我参与11月更文挑战的第 4 天,活动详情查看:2021最后一次更文挑战

原题链接

746. 使用最小花费爬楼梯 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

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

参数限制

  • cost 的长度范围是 [2, 1000]
  • cost[i] 将会是一个整型数据,范围为 [0, 999] 。

分析

阅读题目,我们可以提炼一下几个点:

  • 爬的每一阶楼梯都需要耗费体力
  • 当我们站在第 n 个台阶时,可以选择从 n-1 跨一步到 n;或者是在 n-2 跨两步到 n,这就是本题中动态规划最核心的状态转移方程
  • 最后一阶需要耗费体力 x,但我们需要跨过去站在楼顶,请仔细品,这里隐藏的一个条件是,我们其实需要跨过题目中并未显示提及的楼顶台阶,这个台阶耗费的体力是 0

题目要求我们计算最小的体力耗费,那么我们站上第 n 个台阶时,耗费的体力为 f(n) = Math.min(f(n-2), f(n-1)) + cost[n]

代码

var minCostClimbingStairs = function(cost) {
    cost.push(0)
    let arr = [cost[0],cost[1]];
    for(let i=2;i<cost.length;i++){
        arr[i]=Math.min(arr[i-1],arr[i-2])+cost[i];
    }
    return arr.pop();
};

这份代码就是一个经典的 dp 表计算

优化

由于我们计算 f(n) 时,只需要关注 f(n-2), f(n-1) 的数据,可以将 dp 表简化为 a, b 两个变量存储 f(n-2), f(n-1) 的值

var minCostClimbingStairs = function(cost) {
    cost.push(0)
    let [a,b] = [cost[0],cost[1]];
    let temp;
    for(let i=2;i<cost.length;i++){
        temp = b;
        b=Math.min(a,b)+cost[i];
        a=temp;
    }
    return b;
};

今天的力扣刷题就分享到这里,感谢大家的阅读~