leetcode 407 Trapping Rain Water II
z

Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.

Note:

Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000.

Example:

1
2
3
4
5
6
7
8
Given the following 3x6 height map:
[
[1,4,3,1,3,2],
[3,2,1,3,2,4],
[2,3,3,2,3,1]
]

Return 4.

img

The above image represents the elevation map [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.

img

After the rain, water is trapped between the blocks. The total volume of water trapped is 4.


  • 我们从matrix的四周出发,一次将四周的点都保存到一个qriorityqueue中
  • 每次从queue中取出height最小的点t,从t出发,遍历他的四周的点s,如果s<t,说明s肯定能够trap住water的,而且,由于当前t是四周最小的点,所以s能够trap住(s-t)的water
  • 更新t中的height,将t加入pq中,直到所有的点都遍历完
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
class Cell {
int x;
int y;
int val;
public Cell(int x, int y, int val) {
this.x = x;
this.y = y;
this.val = val;
}
}

public int trapRainWater(int[][] heightMap) {
if (heightMap == null || heightMap.length == 0 || heightMap[0].length == 0)
return 0;
PriorityQueue<Cell> pq = new PriorityQueue(1, new Comparator<Cell>(){
public int compare(Cell a, Cell b) {
return a.val - b.val;
}
});
int water = 0;
int m = heightMap.length;
int n = heightMap[0].length;
boolean[][] visit = new boolean[m][n];
int[][] directions = new int[][]{{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
// 处理四周的cell
for (int i=0; i<m; i++) {
visit[i][0] = true;
visit[i][n-1] = true;
pq.offer(new Cell(i, 0, heightMap[i][0]));
pq.offer(new Cell(i, n-1, heightMap[i][n-1]));
}

for (int i=0; i<n; i++) {
visit[0][i] = true;
visit[m-1][i] = true;
pq.offer(new Cell(0, i, heightMap[0][i]));
pq.offer(new Cell(m-1, i, heightMap[m-1][i]));
}

while (! pq.isEmpty()) {
Cell t = pq.poll();
for (int[] d: directions) {
int x = d[0] + t.x;
int y = d[1] + t.y;
if (x>=0 && x < m && y>=0 && y<n && !visit[x][y]) {
visit[x][y] = true;
water += Math.max(0, t.val - heightMap[x][y]);
pq.offer(new Cell(x, y, Math.max(t.val, heightMap[x][y])));
}
}
}
return water;
}
}