407.trapping-rain-water-ii.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. func trapRainWater(heightMap [][]int) (water int) {
  2. m := len(heightMap)
  3. if m == 0 {
  4. return
  5. }
  6. n := len(heightMap[0])
  7. if n == 0 {
  8. return
  9. }
  10. visited := make([][]bool, m)
  11. for i := 0; i < m; i++ {
  12. visited[i] = make([]bool, n)
  13. }
  14. var pq PriorityQueue
  15. for i := 0; i < m; i++ {
  16. heap.Push(&pq, []int{heightMap[i][0], 0, i})
  17. heap.Push(&pq, []int{heightMap[i][n-1], n - 1, i})
  18. }
  19. for i := 1; i < n-1; i++ {
  20. heap.Push(&pq, []int{heightMap[0][i], i, 0})
  21. heap.Push(&pq, []int{heightMap[m-1][i], i, m - 1})
  22. }
  23. max := 0
  24. for pq.Len() != 0 {
  25. cell := heap.Pop(&pq).([]int)
  26. if max < cell[0] {
  27. max = cell[0]
  28. }
  29. for i := 0; i < 4; i++ {
  30. nx, ny := cell[1]+dx[i], cell[2]+dy[i]
  31. if 0 < nx && nx < n-1 && 0 < ny && ny < m-1 && !visited[ny][nx] {
  32. h := heightMap[ny][nx]
  33. if h < max {
  34. water += max - h
  35. }
  36. heap.Push(&pq, []int{h, nx, ny})
  37. visited[ny][nx] = true
  38. }
  39. }
  40. }
  41. return
  42. }
  43. var dx []int = []int{1, 0, -1, 0}
  44. var dy []int = []int{0, 1, 0, -1}
  45. type PriorityQueue [][]int
  46. func (pq PriorityQueue) Len() int { return len(pq) }
  47. func (pq PriorityQueue) Less(i, j int) bool { return pq[i][0] < pq[j][0] }
  48. func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
  49. func (pq *PriorityQueue) Push(x interface{}) {
  50. *pq = append(*pq, x.([]int))
  51. }
  52. func (pq *PriorityQueue) Pop() interface{} {
  53. x := (*pq)[pq.Len()-1]
  54. *pq = (*pq)[:pq.Len()-1]
  55. return x
  56. }