[前端]_一起刷leetcode 746. 使用最小花费爬楼梯

186 阅读2分钟

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

746. 使用最小花费爬楼梯

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

思路:

  1. 计算出到达每一个台阶时,最小的花费是多少, 存储在数组dp中;
  2. 想到达第i格台阶, 就需要从i - 1或者i - 2处出发;
  3. 所以我们只需要对Math.min(dp[i-1], dp[i-2])进行求解;
  4. 我们只需要保证每一次我们走的都是最优解,那么结果必然是最优的;
  5. 最终对到达终点n的求解就是Math.min(dp[n-1], dp[n-2])

实现:

/**
 * @param {number[]} cost
 * @return {number}
 */
var minCostClimbingStairs = function(cost) {
    let n = cost.length;
    let dp = new Array(n).fill(0);

    dp[0] = cost[0];
    dp[1] = cost[1];
    
    for (let i = 2; i < n; i++) {
        dp[i] = Math.min(dp[i - 2], dp[i - 1]) + cost[i];
    }

    return Math.min(dp[n - 1], dp[n - 2]);
};

优化

实际上我们并不需要记录所有的结果,只需要保存上一步和上上步的结果即可,所以可以对内存空间做出如下优化:

  1. 取消用dp来存储所有步数的最优解;
  2. 新增变量prev1prev2来保存上一步和上上步的值;
  3. 最终我们只需要比较走到第n步的Math.min(prev1, prev2)即可。

优化代码

/**
 * @param {number[]} cost
 * @return {number}
 */
var minCostClimbingStairs = function(cost) {
    let n = cost.length;
    let prev1 = cost[0], prev2 = cost[1];
    
    for (let i = 2; i < n; i++) {
        let cur = Math.min(prev1, prev2) + cost[i];
        prev1 = prev2;
        prev2 = cur;
    }

    return Math.min(prev1, prev2);
};

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。