64. 最小路径和
mid
给定一个包含非负整数的 *m* x *n*
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
**说明:**每次只能向下或者向右移动一步。
回溯
常规做法,剪个枝,结果还是超时了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| import "math"
func minPathSum(grid [][]int) int {
res := math.MaxInt32
m, n := len(grid), len(grid[0])
var dfs func(x, y, sum int)
dfs = func(x, y, sum int) {
if x >= m || y >= n {
return
}
sum += grid[x][y]
if x == m-1 && y == n-1 {
if sum <= res {
res = sum
}
return
}
if sum >= res {
// 剪枝
return
}
dfs(x+1, y, sum)
dfs(x, y+1, sum)
}
dfs(0, 0, 0)
return res
}
|
DP
二维 DP,乃是正解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| func min(a, b int) int {
if a < b {
return a
}
return b
}
func minPathSum(grid [][]int) int {
m, n := len(grid), len(grid[0])
dp := make([][]int, m)
for i := 0; i < m; i++ {
dp[i] = make([]int, n)
}
dp[0][0] = grid[0][0]
// 填充第一行和第一列
for x := 1; x < m; x++ {
dp[x][0] = dp[x-1][0] + grid[x][0]
}
for y := 1; y < n; y++ {
dp[0][y] = dp[0][y-1] + grid[0][y]
}
for x := 1; x < m; x++ {
for y := 1; y < n; y++ {
dp[x][y] = min(dp[x-1][y], dp[x][y-1]) + grid[x][y]
}
}
return dp[m-1][n-1]
}
|
好像可以利用原 grid
的空间,不想写了。