尝试过DFS搜索最小边界写这道题,很麻烦,总有反例。
正手应该是模拟水面上升,比较容易懂。
随着水面上升,
从边界一点点往内部渗透,
当成功渗透内部单元后,
内部单元成为新的边界。
class Solution {
public:
struct Node{
int h;
int x;
int y;
Node(int a,int b,int c):h(a),x(b),y(c){};
bool operator < (const Node a) const{
if(a.h < this->h) return true;
return false;
}
};
int trapRainWater(vector<vector<int>>& heightMap) {
int R = heightMap.size();
if( R <= 2) return 0;
int C = heightMap[0].size();
if( C <= 2) return 0;
priority_queue<Node,vector<Node>> q;
vector<vector<int>> v(R,vector<int>(C,0));
const int dirx[] = {-1,0,1,0};
const int diry[] = {0,1,0,-1};
for(int i=0;i<R;i++){
q.push(*(new Node(heightMap[i][0],i,0)));
q.push(*(new Node(heightMap[i][C-1],i,C-1)));
v[i][0] = v[i][C-1] = 1;
}
for(int j=0;j<C;j++){
q.push(*(new Node(heightMap[0][j],0,j)));
q.push(*(new Node(heightMap[R-1][j],R-1,j)));
v[0][j] = v[R-1][j] = 1;
}
int mWall = 0;
int ans = 0;
while(!q.empty()){
int h = q.top().h;
int x = q.top().x;
int y = q.top().y;
q.pop();
mWall = max(mWall,h);
for(int i=0;i<4;i++){
int r = x + dirx[i];
int c = y + diry[i];
if(r < 1 || r >= R-1 || c < 1 || c >= C-1 || v[r][c]) continue;
v[r][c] = 1;
if(heightMap[r][c] < mWall){
ans += mWall - heightMap[r][c];
heightMap[r][c] = mWall;
}
q.push(*(new Node(heightMap[r][c],r,c)));
}
}
return ans;
}
};