2021.05.06二维矩阵接雨水
(题目来源:https://leetcode-cn.com/problems/trapping-rain-water/)
题目描述
给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。
思路
- 回忆 接雨水1,我们维护了接雨水时的左右最短边界。引申到二维数组接雨水,我们需要维护的时一个矩形边框(到后期可能是一个不规则的边框)。
- dfs遍历+优先数组
代码
public int trapRainWater(int[][] map) {
int m = map.length;
int n = map[0].length;
Queue<int[]> q = new PriorityQueue<int[]>(new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) { //优先队列的头是最小元素
return o1[2]-o2[2];
}
});
boolean[][] isVis = new boolean[m][n];
int[] dir = {-1,0,1,0,-1};
int res = 0;
for(int i = 0; i < m; i++) {
q.offer(new int[] {i,0,map[i][0]});
q.offer(new int[] {i,n-1,map[i][n-1]});
isVis[i][0] = true;
isVis[i][n-1] = true;
}
for(int j = 1; j < n-1; j++) {
q.offer(new int[] {0,j,map[0][j]});
q.offer(new int[] {m-1,j,map[m-1][j]});
isVis[0][j] = true;
isVis[m-1][j] = true;
}
while(!q.isEmpty()) {
int[] cur = q.poll();
isVis[cur[0]][cur[1]] = true;
for(int i = 0; i < 4; i++) {
int nx = cur[0]+dir[i];
int ny = cur[1]+dir[i+1];
if(nx >= 0 && nx < m && ny >= 0 && ny < n && !isVis[nx][ny]) {
res += (cur[2] > map[nx][ny] ? cur[2]-map[nx][ny] : 0);
//无论是否灌入雨水,都要更新边界高度。
q.offer(new int[] {nx,ny,Math.max(cur[2], map[nx][ny])});
isVis[nx][ny] = true;
}
}
}
return res;
}