剑指 Offer II 088. 爬楼梯的最少成本

97 阅读1分钟

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

描述

数组的每个下标作为一个阶梯,第 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 。
  • 提示:
  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

进阶: 能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案?

解析

这题需要注意题目中所说的“一开始可以选择前2节楼梯”和“到达楼层顶部”,所以我们先把题目表达重新组织一下:我们有一个长度为n+2的数组newCost代表每节楼梯的费用(n是原来cost数组的长度),其中newCost[0] = newCost[n+1] = 0,newCost[i] = cost[i - 1] 1 <= i <= n,这样题目就变成了求从下标0跳到下标n+1的最小费用。

因此:典型的动态规划,要到达台阶i,只能从i-1或i-2上来,所以能轻易得到动态规划方程。要使i-1和i-2有意义,所以初始化前两项就可以。

求解动态规划的关键在于明确dp[i]的含义,根据题意找到动态规划方程,其次注意边界的初始化。

class Solution {
    public int minCostClimbingStairs(int[] cost) {
    //  创建一个动态规划数组
    int[] dp=new int[cost.length+1];
    // 初始动态规划数组
    dp[0]=0;
    dp[1]=0;
    for(int i=2;i<=cost.length;i++){
        dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
    }
    return dp[cost.length];
    }
}

运行结果:

执行结果:通过

执行用时:24 ms, 在所有 Java 提交中击败了870.00%的用户

内存消耗:1 MB, 在所有 Java 提交中击败了82.12%的用户