Leetcode407. 接雨水 II
思路:优先队列
维护边缘的最小堆,因为边缘格子不能接水,使用一个数组标记无法接水或者已经访问的格子,保证每个格子最多只需要遍历一次,每次从最小堆中找到最小的围墙,比它矮的其它未被访问的格子一定是可以接水的,更新一下答案,并将其高度入堆
时间复杂度: O ( M N l o g ( M N ) O(MNlog(MN) O(MNlog(MN),维护一个优先队列
空间复杂度: O ( M N ) O(MN) O(MN)维护一个标记的矩阵
typedef pair<int, int> PII;
class Solution {
public:
int trapRainWater(vector<vector<int>>& heightMap) {
priority_queue<PII, vector<PII>, greater<PII>> q;
int n = heightMap.size(), m = heightMap[0].size();
if (n < 2 || m < 2) return 0;
vector<vector<bool>> visit(n, vector<bool>(m, false));
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
if (i == 0 || i == n - 1 || j == 0 || j == m - 1)
{
q.push({heightMap[i][j], i * m + j});
visit[i][j] = true;
}
int res = 0;
int dr[5] = {-1, 0, 1, 0, -1};
while (q.size()) {
PII t = q.top();
q.pop();
for (int i = 0; i < 4; i ++ ) {
int dx = t.second / m + dr[i];
int dy = t.second % m + dr[i + 1];
if (dx >= 0 && dx < n && dy >= 0 && dy < m && !visit[dx][dy]) {
if (heightMap[dx][dy] < t.first) {
res += t.first - heightMap[dx][dy];
}
visit[dx][dy] = true;
q.push({max(heightMap[dx][dy], t.first), dx * m + dy});
}
}
}
return res;
}
};