「这是我参与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;
};
今天的力扣刷题就分享到这里,感谢大家的阅读~