整体是一个优先队列的dfs/bfs。
预处理,最土地之外的高度是0,对于高度小于0的土地,直接在ans上加上其绝对值,然后土地高度变成0。
先把外面一圈的土地入优先队列,每次取出最小的去更新与其有关的 土地(土地的高度是小于当前取出的土地),然后继续优化与其有关的土地的有关的土地,当我们遇到了一块与他大的土地,把当前土地进入优先队列,停止有关土地的寻找。
class Solution {
public:
const int ax[4] = {1, 0, 0, -1};
const int ay[4] = {0, 1, -1, 0};
int maze[120][120], visit[120][120], ans = 0, n, m;
struct point {
int x, y, h;
point(int _x, int _y, int _h) : x(_x), y(_y), h(_h) {}
bool operator < (const point & t) const {
return h > t.h;
}
};
priority_queue<point> q;
bool judge(int x, int y) {
if(x >= 0 && x < n && y >= 0 && y < m && !visit[x][y]) return true;
return false;
}
void dfs(point p, int h) {
visit[p.x][p.y] = 1;
if(p.h >= h) {
q.push(p);
return ;
}
ans += h - p.h;
for(int i = 0; i < 4; i++) {
int tempx = p.x + ax[i];
int tempy = p.y + ay[i];
if(judge(tempx, tempy))
dfs(point(tempx, tempy, maze[tempx][tempy]), h);
}
}
int trapRainWater(vector<vector<int>>& heightMap) {
n = heightMap.size(), m = heightMap[0].size();
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
visit[i][j] = 0;
maze[i][j] = heightMap[i][j];
if(heightMap[i][j] < 0) maze[i][j] = 0, ans -= heightMap[i][j];
if(i == 0 || j == 0 || i == n - 1 || j == m - 1) {
visit[i][j] = 1;
q.push(point(i, j, maze[i][j]));
}
}
while(!q.empty()) {
point temp = q.top();
q.pop();
for(int i = 0; i < 4; i++) {
int tempx = temp.x + ax[i];
int tempy = temp.y + ay[i];
if(judge(tempx, tempy))
dfs(point(tempx, tempy, maze[tempx][tempy]), temp.h);
}
}
return ans;
}
};
Leetcode:407. 接雨水 II(优先队列的dfs/bfs)
原文:https://www.cnblogs.com/lifehappy/p/12864594.html