746. 使用最小花费爬楼梯

746. 使用最小花费爬楼梯

一、题目描述

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值cost[i](下标从 0 开始)。

每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。

请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。

1
2
3
输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。
1
2
3
输入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出:6
解释:最低花费方式是从 cost[0] 开始,逐个经过那些 1 ,跳过 cost[3] ,一共花费 6 。

二、解题思路

假设此时要计算走到第i个阶梯的花费,那么有2种情况可以做到:

  1. 此时站在 i - 1 阶梯上,迈1步走上第i个阶梯,需要花费 cost[i - 1];
  2. 此时站在 i - 2 阶梯上,迈2步走上第i个阶梯,需要花费 cost[i - 2]

因此走到第i个阶梯的最小花费就是:

1
minCost[i] = min(minCost[i - 1] + cost[i - 1], minCost[i - 2] + cost[i - 2]);

题目的要求是走过n个阶梯,并不是走到第n个阶梯。

也就是说,实际上应该是要走到第 n + 1 个阶梯上面,所以最终求的结果应该是 minCost[n + 1]

三、复杂度分析

  • 时间 O(n)
  • 空间 O(1)

四、参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 使用最小花费爬楼梯
*
* @param cost 数组
* @return 最小花费
*/
private int minCostClimbingStairs(int[] cost) {
// 求走到第 n + 1 阶梯的花费
int[] minCost = new int[cost.length + 1];
for (int i = 0; i < minCost.length; i++) {
if (i > 1) {
minCost[i] = Math.min(minCost[i - 1] + cost[i - 1], minCost[i - 2] + cost[i - 2]);
} else {
minCost[i] = 0;
}
}
return minCost[minCost.length - 1];
}

优化空间,因为只用到了 minCost[i - 1]minCost[i - 2],所以直接用2个变量保存就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 使用最小花费爬楼梯
*
* @param cost 数组
* @return 最小花费
*/
private int minCostClimbingStairs(int[] cost) {
int minCost = 0, minCost1 = 0, minCost2 = 0;
for (int i = 2; i < cost.length + 1; i++) {
minCost = Math.min(minCost1 + cost[i - 1], minCost2 + cost[i - 2]);
minCost2 = minCost1;
minCost1 = minCost;
}
return minCost;
}
作者

jiaduo

发布于

2022-09-18

更新于

2023-04-02

许可协议