2021-07-15:接雨水 II。给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。
福大大 答案2021-07-15:
小根堆+是否访问矩阵。思路跟昨天的每日一题差不多,但代码相对复杂。昨天的每日一题,是两端的柱子逐步向中间移动,收集到的雨水就是答案。今天的每日一题,是一圈的柱子逐个向中间移动,收集到的雨水就是答案。一圈的柱子需要放在小根堆中。新增矩阵记录是否访问过。
时间复杂度:O(NNlogN)。
空间复杂度:约O(N*N)。
代码用golang编写。代码如下:
package main import ( "fmt" "sort" ) func main() { heightMap := [][]int{ {1, 4, 3, 1, 3, 2}, {3, 2, 1, 3, 2, 4}, {2, 3, 3, 2, 3, 1}, } ret := trapRainWater(heightMap) fmt.Println(ret) } func trapRainWater(heightMap [][]int) int { if len(heightMap) == 0 || len(heightMap[0]) == 0 { return 0 } N := len(heightMap) M := len(heightMap[0]) isEnter := make([][]bool, N) for i := 0; i < N; i++ { isEnter[i] = make([]bool, M) } heap := make([]*Node, 0) for col := 0; col < M-1; col++ { isEnter[0][col] = true Push(&heap, NewNode(heightMap[0][col], 0, col)) } for row := 0; row < N-1; row++ { isEnter[row][M-1] = true Push(&heap, NewNode(heightMap[row][M-1], row, M-1)) } for col := M - 1; col > 0; col-- { isEnter[N-1][col] = true Push(&heap, NewNode(heightMap[N-1][col], N-1, col)) } for row := N - 1; row > 0; row-- { isEnter[row][0] = true Push(&heap, NewNode(heightMap[row][0], row, 0)) } water := 0 max := 0 for Len(&heap) > 0 { cur := Pop(&heap) max = getMax(max, cur.Val) r := cur.Row c := cur.Col if r > 0 && !isEnter[r-1][c] { water += getMax(0, max-heightMap[r-1][c]) isEnter[r-1][c] = true Push(&heap, NewNode(heightMap[r-1][c], r-1, c)) } if r < N-1 && !isEnter[r+1][c] { water += getMax(0, max-heightMap[r+1][c]) isEnter[r+1][c] = true Push(&heap, NewNode(heightMap[r+1][c], r+1, c)) } if c > 0 && !isEnter[r][c-1] { water += getMax(0, max-heightMap[r][c-1]) isEnter[r][c-1] = true Push(&heap, NewNode(heightMap[r][c-1], r, c-1)) } if c < M-1 && !isEnter[r][c+1] { water += getMax(0, max-heightMap[r][c+1]) isEnter[r][c+1] = true Push(&heap, NewNode(heightMap[r][c+1], r, c+1)) } } return water } type Node struct { Val int Row int Col int } func NewNode(v int, r int, c int) *Node { ret := &Node{} ret.Val = v ret.Row = r ret.Col = c return ret } func Push(heap *[]*Node, node *Node) { *heap = append(*heap, node) } func Pop(heap *[]*Node) *Node { sort.Slice(*heap, func(i, j int) bool { return (*heap)[i].Val < (*heap)[j].Val }) ans := (*heap)[0] *heap = (*heap)[1:] return ans } func Len(heap *[]*Node) int { return len(*heap) } func getMax(a int, b int) int { if a > b { return a } else { return b } }
执行结果如下: