题目来源于力扣(LeetCode)
题目相关标签:数组、动态规划
说明:
cost
的长度将会在[2, 1000]
。- 每一个
cost[i]
将会是一个Integer类型,范围为[0, 999]
。
定义两个变量:dp1,dp2,初始值均为 0
遍历数组,每一项的结果都取两个变量中的最小值
得到本次遍历计算得到的结果后,改变 dp1,dp2 的值
dp2 原本的值(即前 2 项元素的值)舍弃,改变为原本 dp1(前 1 项元素)的值
dp1 改变为记录本次遍历计算得到的结果
遍历结束后,再返回 dp1 和 dp2 两值中的最小值
定义一个与 cost 数组长度相同的数组,用于记录每一步花费的力气数
手动为新数组的前两项赋值为 cost 数组的前两项元素
遍历 cost 数组(从第 3 项开始,索引为 2)
每次遍历都将当前遍历元素与新数组中的前一项和前两项进行相同,将得到的两个结果再取最小值存储到新数组中,则本次计算得到的值将作为下一个元素进行相加的值
因最后两步时,可以是倒数第两步时,直接两步走完,也可以是倒数第一步时,再走一步走完,所以最后对比新数组中倒数第一项和倒数第二项的值,返回最小值
public static int minCostClimbingStairs(int[] cost) {
int dp1 = 0, dp2 = 0;
for (int i = 0; i < cost.length; i++) {
// 当前遍历元素加上前两个元素中的较小值
int temp = cost[i] + Math.min(dp1, dp2);
// 记录前 2 位元素的变量改为记录前 1 位元素
dp2 = dp1;
// 记录前 1 位元素的变量改为记录当前计算得到的值
dp1 = temp;
}
// 最后比较 dp1 和 dp2 的大小
return Math.min(dp1, dp2);
}
public static int minCostClimbingStairs2(int[] cost) {
// 数组记录每一步花费的力气数
int[] dpArr = new int[cost.length];
dpArr[0] = cost[0];
dpArr[1] = cost[1];
for (int i = 2; i < cost.length; i++) {
int dp1 = dpArr[i - 2] + cost[i];
int dp2 = dpArr[i - 1] + cost[i];
// 走每一步都判断与前一步和前两步时,怎么走(跨一步还是跨两步)花费的力气最小
dpArr[i] = Math.min(dp1, dp2);
}
// 最后一步与最后两步中取最小值,因为倒数第二步时,也可以直接跳完
return Math.min(dpArr[dpArr.length - 1], dpArr[dpArr.length - 2]);
}
public static void main(String[] args) {
int[] cost = {10, 15, 20}; // output:15
// int[] cost = {1, 100, 1, 1, 1, 100, 1, 1, 100, 1}; // output:6
int result = minCostClimbingStairs(cost);
System.out.println(result);
}
原文:https://www.cnblogs.com/zhiyin1209/p/12969565.html