积水问题(动态规划)
有一组不同高度的台阶,有一个整数组数表示,数组中每个数是台阶的高度。当开始下雨(水足够的多),台阶之间的水坑会积多少水呢?
如图:数组为[0,1,2,1,0,1,3,2,1,2,1,0], 积水为5
问题分析
每一栏能存多少水取决于左边最高栏和右边最高栏里面取较小值,然后与自己栏 相减得出结果,如图
1、先按照左边,去找最右边最高的墙
// [0 1 2 1 0 1 3 2 1 2 1 0]
// [0 1 2 2 2 2 3 3 3 3 3 3]
var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
var leftS []int
for i := 0; i < len(s); i++ {
if i == 0 {
leftS = append(leftS, s[0])
continue
}
if s[i] > leftS[len(leftS)-1] {
leftS = append(leftS, s[i])
} else {
leftS = append(leftS, leftS[len(leftS)-1])
}
}
2、同理再按照右边,去找最左边最高的墙
//[0 1 2 1 0 1 3 2 1 2 1 0]
//[3 3 3 3 3 3 3 2 2 2 1 0]
var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
rightS := make([]int, len(s))
for i := len(s) - 1; i >= 0; i-- {
if i == len(s)-1 {
rightS[i] = s[i]
continue
}
if s[i] > rightS[i+1] {
rightS[i] = s[i]
} else {
rightS[i] = rightS[i+1]
}
}
3、然后求出每一栏的积水(左边最高和右边最高的较小值 ➖当前高度)
var total int
for i := 0; i < len(s); i++ {
var a int
if rightS[i] > leftS[i] {
a = leftS[i] - s[i]
} else {
a = rightS[i] - s[i]
}
total += a
}
全部代码
var s = []int{0, 1, 2, 1, 0, 1, 3, 2, 1, 2, 1, 0}
var leftS []int
rightS := make([]int, len(s))
for i := 0; i < len(s); i++ {
if i == 0 {
leftS = append(leftS, s[0])
continue
}
if s[i] > leftS[len(leftS)-1] {
leftS = append(leftS, s[i])
} else {
leftS = append(leftS, leftS[len(leftS)-1])
}
}
for i := len(s) - 1; i >= 0; i-- {
if i == len(s)-1 {
rightS[i] = s[i]
continue
}
if s[i] > rightS[i+1] {
rightS[i] = s[i]
} else {
rightS[i] = rightS[i+1]
}
}
var total int
for i := 0; i < len(s); i++ {
var a int
if rightS[i] > leftS[i] {
a = leftS[i] - s[i]
} else {
a = rightS[i] - s[i]
}
total += a
}
fmt.Println(total)