70. 爬楼梯
这个题的思路就是倒推,因为到最后一节楼梯n,可以用n-1走一步到达也可以有n-2走两部达到,所以到达n的方法有n-1 + n-2,因为有n-2 所以要初始话至少前两个也就是dp[0]和dp[1]
方法一
借助数组缓存
var climbStairs = function (n) {
const dp = [1, 1];
// 这里需要爬到n i要到达n即i <= n;
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
};
方法二
借助变量
var climbStairs = function (n) {
let pre = 1, cur = 1;
for (let i = 2; i <= n; i++) {
// 需要把 cur赋值给pre 所以需要先临时保存cur
const temp = cur;
cur = cur + pre;
pre = temp;
}
return cur;
};
746. 使用最小花费爬楼梯
------------------------------ 二刷心得 —————————————————————————
这道题5个月之前写过,重新在写还是有问题,没有一次写下来,这次重新看题目看题解,找解题思路,最后仔细阅读题目,发现比较好理解的解法还是方法二,只不过是麻烦一点儿,但是最想想到的还是方法一的解法,但最后要加cost[i]对我来说不好理解
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。
方法二 也就是官方给出的解题思路,是仔细读题目完全按照题目的核心就是,到达楼顶有两种方式取最小值
1 从倒数第二个台阶上两阶dp[i-2] + cost[i-2]
2 从倒数第一个台阶上一阶dp[i-1] + cost[i-1]
dp[i] 表示达到下标 i 的阶梯最小花费. 因为从倒数第二到达i的最小花费就是需要-> 到达倒数第二阶所花费的最小值dp[i-2]➕从倒数第二阶往上到i需要花费的cost[i-2]; 从倒数第一阶同理.
其次,还需要确定初始值就是dp[0]dp[1]的值, 这样看是相对题目最容易理解的解法.
方法一 也好理解也不好理解,我来说从题目出发,不好理解,就不过多解释了,但是代码其实也简单,具体如下
------------------------------ 二刷心得 —————————————————————————\
方法一
到达第i个台阶所花费的最少体力为dp[i],
var minCostClimbingStairs = function (cost) {
const n = cost.length;
const dp = [cost[0], cost[1]];
// cost.push(0)
for (let i = 2; i <= n; i++) {
// **注意这里为什么是加cost[i],而不是cost[i-1],cost[i-2]之类的**,因为题目中说了:每当你爬上一个阶梯你都要花费对应的体力值
dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i]
}
return Math.min(dp[n - 1], dp[n - 2])
};
方法二
按照题目描述,那么这个官方给出的方法最好理解,也是借助一个dp,初始前两个值都为0,比较思路和
var minCostClimbingStairs = function(cost) {
const n = cost.length;
const dp = new Array(n + 1);
dp[0] = dp[1] = 0;
for (let i = 2; i <= n; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[n];
};
上面用一个新数组dp,其实可以不用,直接使用cost就行因为到达cost[i]就是比较cost[i-1]和cost[i-2],取其最小值就行
const costLen = cost.length;
for (let i = 2; i < costLen; i++) {
cost[i] += Math.min(cost[i - 1], cost[i - 2]);
}
return Math.min(cost[costLen - 1], cost[costLen - 2]);