给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
示例 1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
2
3 4
6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
示例 2:
输入:triangle = [[-10]]
输出:-10
提示:
- 1 <= triangle.length <= 200
- triangle[0].length == 1
- triangle[i].length == triangle[i – 1].length + 1
- -10^4 <= triangle[i][j] <= 10^4
解题:
func minimumTotal(triangle [][]int) int {
if triangle == nil {
return 0
}
n := len(triangle)
for i := 1; i < n; i++ {
lv := len(triangle[i]) - 1
triangle[i][0] += triangle[i-1][0]
for j := 1; j < lv; j++ {
triangle[i][j] += min(triangle[i-1][j-1], triangle[i-1][j])
}
triangle[i][lv] += triangle[i-1][lv-1]
}
minNum := math.MaxInt
for _, v := range triangle[n-1] {
if v < minNum {
minNum = v
}
}
return minNum
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
官方解答:
1.动态规划
func minimumTotal(triangle [][]int) int {
n := len(triangle)
f := make([][]int, n)
for i := 0; i < n; i++ {
f[i] = make([]int, n)
}
f[0][0] = triangle[0][0]
for i := 1; i < n; i++ {
f[i][0] = f[i-1][0] + triangle[i][0]
for j := 1; j < i; j++ {
f[i][j] = min(f[i-1][j-1], f[i-1][j]) + triangle[i][j]
}
f[i][i] = f[i-1][i-1] + triangle[i][i]
}
ans := math.MaxInt32
for i := 0; i < n; i++ {
ans = min(ans, f[n-1][i])
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
2.动态规划 + 空间优化
func minimumTotal(triangle [][]int) int {
n := len(triangle)
f := [2][]int{}
for i := 0; i < 2; i++ {
f[i] = make([]int, n)
}
f[0][0] = triangle[0][0]
for i := 1; i < n; i++ {
curr := i % 2
prev := 1 - curr
f[curr][0] = f[prev][0] + triangle[i][0]
for j := 1; j < i; j++ {
f[curr][j] = min(f[prev][j-1], f[prev][j]) + triangle[i][j]
}
f[curr][i] = f[prev][i-1] + triangle[i][i]
}
ans := math.MaxInt32
for i := 0; i < n; i++ {
ans = min(ans, f[(n-1)%2][i])
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
优化
func minimumTotal(triangle [][]int) int {
n := len(triangle)
f := make([]int, n)
f[0] = triangle[0][0]
for i := 1; i < n; i++ {
f[i] = f[i-1]+triangle[i][i]
for j := i - 1; j> 0;j-- {
f[j] = min(f[j-1], f[j])+triangle[i][j]
}
f[0] += triangle[i][0]
}
ans := math.MaxInt32
for i := 0; i < n; i++ {
ans = min(ans, f[i])
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}