算法: 最小花费爬楼梯的四种解法 746. Min Cost Climbing Stairs

Posted 架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法: 最小花费爬楼梯的四种解法 746. Min Cost Climbing Stairs相关的知识,希望对你有一定的参考价值。

746. Min Cost Climbing Stairs

You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps.

You can either start from the step with index 0, or the step with index 1.

Return the minimum cost to reach the top of the floor.

Example 1:

Input: cost = [10,15,20]
Output: 15
Explanation: You will start at index 1.
- Pay 15 and climb two steps to reach the top.
The total cost is 15.

Example 2:

Input: cost = [1,100,1,1,1,100,1,1,100,1]
Output: 6
Explanation: You will start at index 0.
- Pay 1 and climb two steps to reach index 2.
- Pay 1 and climb two steps to reach index 4.
- Pay 1 and climb two steps to reach index 6.
- Pay 1 and climb one step to reach index 7.
- Pay 1 and climb two steps to reach index 9.
- Pay 1 and climb one step to reach the top.
The total cost is 6.

Constraints:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

1. 分析

我们从第 0 步或第 1 步开始。目标是到达最后一步或倒数第二步,以最小值为准。

步骤 1 - 确定子问题之间的递归关系。在这个问题中,
递归关系:

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

基本情况:

  • mincost(0) = cost[0]
  • mincost(1) = cost[1]

步骤 2 - 将递归关系转换为递归

// Recursive Top Down - O(2^n) Time Limit Exceeded
public int minCostClimbingStairs(int[] cost) {
	int n = cost.length;
	return Math.min(minCost(cost, n-1), minCost(cost, n-2));
}
private int minCost(int[] cost, int n) {
	if (n < 0) return 0;
	if (n==0 || n==1) return cost[n];
	return cost[n] + Math.min(minCost(cost, n-1), minCost(cost, n-2));
}

第 3 步 - 优化 1 - 自上而下 DP - 添加记忆到递归- 从指数到线性。

// Top Down Memoization - O(n) 1ms
int[] dp;
public int minCostClimbingStairs(int[] cost) {
	int n = cost.length;
	dp = new int[n];
	return Math.min(minCost(cost, n-1), minCost(cost, n-2));
}
private int minCost(int[] cost, int n) {
	if (n < 0) return 0;
	if (n==0 || n==1) return cost[n];
	if (dp[n] != 0) return dp[n];
	dp[n] = cost[n] + Math.min(minCost(cost, n-1), minCost(cost, n-2));
	return dp[n];
}

第 4 步 - 优化 2 -自底向上 DP - 将递归转换为迭代- 摆脱递归堆栈

// Bottom up tabulation - O(n) 1ms
public int minCostClimbingStairs(int[] cost) {
	int n = cost.length;
	int[] dp = new int[n];
	for (int i=0; i<n; i++) {
		if (i<2) dp[i] = cost[i];
		else dp[i] = cost[i] + Math.min(dp[i-1], dp[i-2]);
	}
	return Math.min(dp[n-1], dp[n-2]);
}

步骤 5 - 优化 3 - 微调 - 将 O(n) 空间减少到 O(1)。

// Bottom up computation - O(n) time, O(1) space
public int minCostClimbingStairs(int[] cost) {
	int n = cost.length;
	int first = cost[0];
	int second = cost[1];
	if (n<=2) return Math.min(first, second);
	for (int i=2; i<n; i++) {
		int curr = cost[i] + Math.min(first, second);
		first = second;
		second = curr;
	}
	return Math.min(first, second);
}

参考

https://leetcode.com/problems/min-cost-climbing-stairs/discuss/476388/4-ways-or-Step-by-step-from-Recursion-greater-top-down-DP-greater-bottom-up-DP-greater-fine-tuning

以上是关于算法: 最小花费爬楼梯的四种解法 746. Min Cost Climbing Stairs的主要内容,如果未能解决你的问题,请参考以下文章

746. 使用最小花费爬楼梯简单DP

LeetCode 746. 使用最小花费爬楼梯

746使用最小花费爬楼梯

代码随想录算法训练营第三十八天 | 理论基础 ,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯

代码随想录算法训练营第三十八天 | 509. 斐波那契数70. 爬楼梯746. 使用最小花费爬楼梯

746-使用最小花费爬楼梯