官方链接
https://leetcode-cn.com/problems/min-cost-climbing-stairs/
数组的每个索引作为一个阶梯,第 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]
将会是一个 Integer 类型,范围为[0, 999]
。
思路
递归 + 记忆化搜索
时间复杂度 O(n)
空间复杂度 O(n)
dp[i] := min cost to climb to n-th step
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
ans = dp(n)
dp
时间复杂度 O(n)
空间复杂度 O(n) --> O(1)
dp[i] := min cost brfore leaving n-th step
dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
ans = min(dp[i - 1], dp[i - 2])
解法一
class Solution {
public int minCostClimbingStairs(int[] cost) {
Map<Integer, Integer> mem = new HashMap<>();
return helper(mem, cost, cost.length);
}
private int helper(Map<Integer, Integer> mem, int[] cost, int i) {
if (i <= 1) return 0;
if (mem.containsKey(i)) return mem.get(i);
int a = Math.min(helper(mem, cost, i - 1) + cost[i - 1], helper(mem, cost, i - 2) + cost[i - 2]);
mem.put(i, a);
return a;
}
}
解法二
class Solution {
public int minCostClimbingStairs(int[] cost) {
Map<Integer, Integer> mem = new HashMap<>();
return Math.min(helper(mem, cost, cost.length - 1), helper(mem, cost, cost.length - 2));
}
private int helper(Map<Integer, Integer> mem, int[] cost, int i) {
if (i < 0) return 0;
if (mem.containsKey(i)) return mem.get(i);
int a = Math.min(helper(mem, cost, i - 1), helper(mem, cost, i - 2)) + cost[i];
mem.put(i, a);
return a;
}
}
解法三
改为顺推
class Solution {
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n];
dp[0] = cost[0];
dp[1] = cost[1];
for (int i = 2; i < n; i++) {
dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
}
return Math.min(dp[n - 1], dp[n - 2]);
}
}
class Solution {
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 0;
for (int i = 2; i <= n; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[n];
}
}
O(1)
class Solution {
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int dp1 = 0, dp2 = 0;
for (int i = 2; i <= n; i++) {
int dp = Math.min(dp1 + cost[i - 1], dp2 + cost[i - 2]);
dp2 = dp1;
dp1 = dp;
}
return dp1;
}
}