407. Trapping Rain Water II - jiejackyzhang/leetcode-note GitHub Wiki
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:
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.
解题思路为:可以存水的高度受到border中最矮的那一边的限制。 因此可以采用min heap来接,通过PriorityQueue实现。
- 首先将最外圈放入queue,并标记visited,最外圈不能往里注水。
- 然后取出最小的那个,考察它的四面,若unvisited并且比它低,则可以往里注水,并更新它的高度为注水后的高度,把它也放入queue,并标记visited。
- 直到all visited,则能注水的cell都已经注满水了。
public class Solution {
class Cell {
int x;
int y;
int h;
public Cell(int x, int y, int h) {
this.x = x;
this.y = y;
this.h = h;
}
}
public int trapRainWater(int[][] heightMap) {
if(heightMap == null || heightMap.length <= 1 || heightMap[0].length <= 1) return 0;
PriorityQueue<Cell> queue = new PriorityQueue<Cell>(1, new Comparator<Cell>(){
public int compare(Cell A, Cell B) {
return A.h - B.h;
}
});
int m = heightMap.length;
int n = heightMap[0].length;
boolean[][] visited = new boolean[m][n];
for(int i = 0; i < m; i++) {
visited[i][0] = true;
visited[i][n-1] = true;
queue.offer(new Cell(i, 0, heightMap[i][0]));
queue.offer(new Cell(i, n-1, heightMap[i][n-1]));
}
for(int j = 0; j < n; j++) {
visited[0][j] = true;
visited[m-1][j] = true;
queue.offer(new Cell(0, j, heightMap[0][j]));
queue.offer(new Cell(m-1, j, heightMap[m-1][j]));
}
int[][] directions = {{0,1},{0,-1},{1,0},{-1,0}};
int sum = 0;
while (!queue.isEmpty()) {
Cell cell = queue.poll();
for (int i = 0; i < 4; i++) {
int x = cell.x + directions[i][0];
int y = cell.y + directions[i][1];
if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) {
visited[x][y] = true;
sum += Math.max(0, cell.h - heightMap[x][y]);
queue.offer(new Cell(x, y, Math.max(heightMap[x][y], cell.h)));
}
}
}
return sum;
}
}