链接
题目.
难度:
high
解答:
这道题其实不难,dp是一定的,关键是dp是从左上角递推呢还是目的地右下角递推。左上角递推涉及到某个位置的余额问题,一个dp搞不定,所以从右下角逆推。代码写的冗余了一点,不过思路清晰。
package main
import "fmt"
func calculateMinimumHP(dungeon [][]int) int {
h := len(dungeon) - 1
v := len(dungeon[0]) - 1
initial := make([][]int, h+1)
for i := 0; i <= h; i++ {
initial[i] = make([]int, v+1)
}
initial[h][v] = 1
if dungeon[h][v] <= 0 {
initial[h][v] = 1 - dungeon[h][v]
}
for j := v - 1; j >= 0; j-- {
min := 1
if res := 1 - dungeon[h][j]; res > min {
min = res
}
if res := initial[h][j+1] - dungeon[h][j]; res > min {
min = res
}
initial[h][j] = min
}
for i := h - 1; i >= 0; i-- {
min := 1
if res := 1 - dungeon[i][v]; res > min {
min = res
}
if res := initial[i+1][v] - dungeon[i][v]; res > min {
min = res
}
initial[i][v] = min
}
for i := h - 1; i >= 0; i-- {
for j := v - 1; j >= 0; j-- {
min := 1
if res := 1 - dungeon[i][j]; res > min {
min = res
}
if initial[i+1][j] < initial[i][j+1] {
if res := initial[i+1][j] - dungeon[i][j]; res > min {
min = res
}
} else {
if res := initial[i][j+1] - dungeon[i][j]; res > min {
min = res
}
}
initial[i][j] = min
}
}
return initial[0][0]
}
func main() {
dungeon := [][]int{
{-2, -3, 3},
{-5, -10, 1},
{10, 30, -5},
}
fmt.Println(calculateMinimumHP(dungeon))
}
复杂度分析
time
O(m*n)
space
O(M*N)
执行结果
执行用时 :
4 ms
, 在所有 Go 提交中击败了
98.31%
的用户
内存消耗 :
3.7 MB
, 在所有 Go 提交中击败了
44.44%
的用户