周末之回顾动态规划
动态规划应该是递归题解的一种求最值的解法,其精髓是怎么找到状态转移方程(本人还未抓到其精髓TT),所以就从简单题回顾起
746. 使用最小花费爬楼梯
题意就是说可以一步走一个台阶或者走两个台阶,走到每个台阶上要花费对应的体力,那怎么走花费的体力最小,典型的最值问题,也是典型的动归问题
var minCostClimbingStairs = function(cost) {
let dp = new Array(cost.length + 1)
// 动归的第一步,设置dp数组,设置默认值,这里从原点开始走,要么走一步要么走两步,所以可以直接设置
dp[0] = cost[0]
dp[1] = cost[1]
for(let i = 2; i < cost.length; i++){
dp[i] = Math.min(dp[i-1],dp[i-2]) + cost[i]
}
return Math.min(dp[cost.length - 1],dp[cost.length - 2])
};
53. 最大子数组和
题意就是说在一个数组中找到最大连续子数组的和
var maxSubArray = function(nums) {
// 数组长度,dp初始化
const [len, dp] = [nums.length, [nums[0]]];
// 最大值初始化为dp[0],因为数组的第一位前面没有元素了,所以仅有第一位为元素的子数组的最大和就是本身
let max = dp[0];
for (let i = 1; i < len; i++) {
// 求每个当前元素的最大的和设置在dp中,dp存储的是当前元素加上前面的元素的最大的和
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
// 更新最大值
max = Math.max(max, dp[i]);
}
return max
};
119. 杨辉三角 II
题意就是三角形中每行每个元素说该元素的上左元素加上上右元素的和
var getRow = function(rowIndex) {
let dp = [[1]] // 三角形的顶端是从1开始
for(let i = 1; i <= rowIndex; i++){
dp[i] = []
for(let j = 0; j <= i; j++){
// 判断左上与右上的值是否存在
let topLeft = dp[i-1][j] ? dp[i-1][j] : 0;
let topright = dp[i-1][j-1] ? dp[i-1][j-1] :0
dp[i][j] = topLeft + topright
}
}
return dp[rowIndex]
};
120. 三角形最小路径和
题意跟上题说相识的,但是这里的最小路径和的意思如果是从下往上就是当前元素的上左上右中选取最小的元素值作为和,反之就是下左下右
var minimumTotal = function(triangle) {
let dp = [], len = triangle.length
// 将dp数组初始化味最后一行的值
for(let i = 0; i < triangle[len-1].length; i++){
dp[i] = triangle[len-1][i]
}
// 从倒数第二行开始累加倒数第一行的元素
for(let i = dp.length - 2; i >= 0; i--){
for(let j = 0; j < len;j++){
// 求最小值
dp[j] = Math.min(dp[j],dp[j+1]) + triangle[i][j]
}
}
return dp[0]
};