力扣746题 力扣https://leetcode-cn.com/problems/min-cost-climbing-stairs/
题目描述
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。
输入:cost = [10, 15, 20] 输出:15 解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。
分析
以输入cost =[1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 分析
第一步可以是cost[0] = 1; 那么从1(0) -> 1(2) ->1(4) ->1(6)->1(7)->1(9); 最后结果为6;
第一步也可以时cost[1] = 100。
那么怎么能保证到最后一步是获取的最小的值呢。
从最后一个元素向前推导。
到达cost[9] 最小有两种情况,前一步行走经过cost[8]或者跳过cost[8]
到达cost[8]最小有两种情况,前一步行走经过cost[7]或者跳过cost[7]
到达cost[7]最小有两种情况,前一步行走经过cost[6]或者跳过cost[6]
.....
以此类推
minCost[9] = min(minCost[8] + cost[9], minCost[7] + cost[8])
minCost[8] = min(minCost[7] + cost[8], minCost[6] + cost[7])
.....
minCost[n] = min(minCost[n-1] + cost[n], minCost[n-2] + cost[n-1]);
代码实现
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int pre1 = cost[0];
int pre2 = cost[1];
for (int i = 2; i < cost.size(); i++) {
// 前一个元素不跳过
int res1 = cost[i] + pre2;
//前一个元素跳过
int res2 = cost[i] + pre1;
pre1 = pre2;
pre2 = min(res1, res2);
}
return min(pre1,pre2);
}
int minCostClimbingStairsEx(vector<int>& cost) {
int n = cost.size();
int prev = 0, curr = 0;
for (int i = 2; i <= n; i++) {
int next = min(curr + cost[i - 1], prev + cost[i - 2]);
prev = curr;
curr = next;
}
return curr;
}
};
时间复杂度:O(n)
空间复杂度:O(1)