文章目录
一、最小路径和:问题解析
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:一个机器人每次只能
向下
或者向右
移动一步。
核心思路:关注每个状态可以执行的操作
- 本题中,只有2个操作,向下,向右;
最小
路径和 = min(向下,向右) - 在
凑零钱
题目中,就是最小
零钱数目 = min(不兑换, 兑换1毛,兑换2毛…) - 在
背包
问题中,就是最大
价值和 = max(不装的价值, 装第1个物品的价值, 装第2个…) - 在
打家劫舍
问题中,就是最大
价值 = max(不打劫, 打劫)
二、最小路径和:问题求解
核心伪代码:res = res + min(向下操作,向右操作)
func minPathSum(grid [][]int) int {
m := len(grid)
n := len(grid[0])
if m == 0{
return 0
}
// 遍历所有的格子,一行行扫过去,直到终点位置
for row:=0; row<m; row++{
for col:=0; col<n; col++{
// 四个分支其实都是一个意思
// res = res + min(向下,向右)
// 将边界情况想象为无穷大的路径,那么自然就不会选择往边界走
// basecase
if row ==0 && col == 0{
continue
}else if row==0{
// 上边界,当前位置,只能从左边移动到此位置
grid[row][col] = grid[row][col] + grid[row][col-1]
}else if col==0{
// 左边界,当前位置,只能从上边移动到此位置
grid[row][col] = grid[row][col] + grid[row-1][col]
}else{
// res = res + min(从左边移到此位置,从上面移到此位置)
grid[row][col] = grid[row][col] + min(grid[row][col-1], grid[row-1][col])
}
}
}
// 目标位置是:(m,n)
return grid[m-1][n-1]
}
func min(a, b int) int {
if a>b{
return b
}
return a
}
提取最小路径和的核心代码
再看看凑零钱
的核心代码
跟最小路径和类似,从第一个格子开始,下一个状态等于min(全部可操作的情况)
再看看打家劫舍
的核心代码
跟前面的动态规划思路一致,都是下一个状态 = min(全部可操作性的情况), 打家劫舍中,只有两种情况可以操作【打劫、不打劫】和最小零钱操作数【向下,向右】一样