给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。
示例:
给出如下 3x6 的高度图:
[
[1,4,3,1,3,2],
[3,2,1,3,2,4],
[2,3,3,2,3,1]
]
返回 4 。
用最小堆维护从外向内的最小元素
每次从最小的元素向四周搜索 比它大直接加入堆 比它小即将总接水量加上它们的差值 然后将新元素入堆(新元素入堆的高为搜索到它的元素的高 可以接到最多的水)
所有搜索过的元素为避免重复搜索 用一个矩阵来记录信息
class Solution {
class pos{
int x;
int y;
int h;
pos(int x, int y, int h){
this.x = x;
this.y = y;
this.h = h;
}
}
public int trapRainWater(int[][] heightMap) {
int n = heightMap.length;
int m = heightMap[0].length;
if(heightMap == null || n == 0 || m == 0)
return 0;
int[][] visited = new int[n][m];
Queue<pos> minheap = new PriorityQueue<>(new Comparator<pos>(){
public int compare(pos a, pos b){
return a.h - b.h;
}
});
for(int i = 0; i < n; i++){
minheap.offer(new pos(i, 0, heightMap[i][0]));
minheap.offer(new pos(i, m - 1, heightMap[i][m-1]));
visited[i][0] = 1;
visited[i][m-1] = 1;
}
for(int j = 0; j < m; j++){
minheap.offer(new pos(0, j, heightMap[0][j]));
minheap.offer(new pos(n - 1, j, heightMap[n-1][j]));
visited[0][j] = 1;
visited[n-1][j] = 1;
}
int[] cx = {0, 1, 0, -1};
int[] cy = {1, 0, -1, 0};
int ret = 0;
while(!minheap.isEmpty()){
pos p = minheap.poll();
for(int i = 0; i < 4; i++){
int newx = p.x + cx[i];
int newy = p.y + cy[i];
if(newx < 0 || newy < 0 || newx >= n || newy >= m || visited[newx][newy] == 1)
continue;
if(heightMap[newx][newy] < p.h){
ret += p.h - heightMap[newx][newy];
minheap.offer(new pos(newx, newy, p.h));
}
else{
minheap.offer(new pos(newx, newy, heightMap[newx][newy]));
}
visited[newx][newy] = 1;
}
}
return ret;
}
}