题库来源:LeetCode 746题
阶梯最小花费问题
题目
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
例如给出 cost = [1,100,1,1,1,100,1,1,100,1]
输出 6
理解
它的意思是你可以从第1个阶梯或第二个阶梯开始向上爬,然后每次只要支付本阶梯的费用后你又能往上爬一个阶梯或两个阶梯,然后重复上面的操作直到到达顶端且费用最少。
分析
这是一个典型的动态规划题目,我们可以清楚的知道如果只有第一阶梯或第二阶梯,那么它们的cost就为0;但是如果要到达第三阶梯,那么第一阶梯就要支付第一阶梯的费用然后爬两阶梯或者第二阶梯支付第二阶梯的费用爬一层就能到达第三阶梯,以此类推,而我们要做的就是把到达每层阶梯的最小值求出来放入dp数组中。
从上面的分析中我们不难得出我们的状态转移方程:
dp[0] = 0 , dp[1] = 0
f = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
dp[i-1]+cost[i-1] 代表第i-1的阶梯支付了它的费用爬一个楼梯到达第i阶
dp[i-2]+cost[i-2] 代表第i-2的阶梯支付了它的费用爬两个楼梯到达第i阶
我们取两个的最小值就能获取到到达第i阶的最小值
代码实现
public int minCostClimbingStairs(int[] cost) {
//创建一个dp数组用于存放到达i层阶梯的最小花费值
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];
}
同理用递归思路也可以实现
class Solution {
HashMap<Integer,Integer> hashMap = new HashMap<>();
public int minCostClimbingStairs(int[] cost) {
return minCost(cost,cost.length);
}
int minCost(int [] cost,int i){
if(i<=1){
return 0;
}
if(hashMap.containsKey(i)){
return hashMap.get(i);
}else{
int res = Math.min(cost[i-1]+minCost(cost,i-1),cost[i-2]+minCost(cost,i-2));
hashMap.put(i,res);
return res;
}
}
}