终于进入动态规划了,要好好学习,争取理解更近一步。
题目一 509. 斐波那契数
思路
- dp数组含义:dp[i]代表i的值,
- dp[i] = dp[i-1] + dp[i-2]
- 初始值:dp[0] = 0, dp[1] = 1
- 从前到后循环求值
var fib = function(n) {
if (n <= 1) {
return n;
}
const dp = [0, 1];
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
};
var fib = function(n) {
if (n <= 1) {
return n;
}
let dp1 = 0;
let dp2 = 1;
for (let i = 2; i <= n; i++) {
const sum = dp1 + dp2;
dp1 = dp2;
dp2 = sum;
}
return dp2;
}
题目二 70. 爬楼梯
思路
其实就是fib的求解,区别在于初始值。
- dp数组含义:dp[i]代表上到底第i个台阶的方法总数。
- dp[i] = dp[i-1] + dp[i-2]
- 初始值:上到第一个台阶有一种方法 dp[1] = 1, 上到第2个台阶有2种(从第一个台阶上一步,从第0个台阶上2步)dp[2] = 2,dp[0]呢,好像应该是0,但是按照这个规律则是1.
- 从前到后循环求值
var climbStairs = function(n) {
if (n <= 2) {
return n;
}
const dp = [1, 1, 2];
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
};
var climbStairs = function(n) {
if (n <= 2) {
return n;
}
let dp1 = 1;
let dp2 = 2;
for (let i = 3; i <= n; i++) {
const sum = dp1 + dp2;
dp1 = dp2;
dp2 = sum
}
return dp2;
};
题目三 746. 使用最小花费爬楼梯
思路
- dp数组含义:dp[i]代表上到达n个台阶的顶楼的最小花费,从i开始上之后花费cost[i],最后一个台阶到最顶层才会耗费最后一个花费。
dp[i] = Math.min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])- 初始值:题目写了可以从第0个或者第一个开始爬楼梯,所以dp0,dp1相等于不需要花费,
- 从前到后循环求值
/**
* @param {number[]} cost
* @return {number}
*/
var minCostClimbingStairs = function(cost) {
const dp = [0, 0];
const len = cost.length;
for (let i = 2; i <= len; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[len];
};
var minCostClimbingStairs = function(cost) {
const len = cost.length;
let dp1 = 0;
let dp2 = 0;
for (let i = 2; i <= len; i++) {
// 这里注意dp1对应cost[i-2] dp2对应cost[i-1]
const newVal = Math.min(dp1 + cost[i - 2], dp2 + cost[i - 1]);
dp1 = dp2;
dp2 = newVal;
}
return dp2;
};