leetcode 407. 接雨水 II (优先队列)

题目简述:

       给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。

                                                                  

题解:

       这个最先思考就是,考虑每一个水池,往外bfs,然后碰到边界就停,然后选择边界最低的那个,把水池填满,但是边界的判断是个难题,不容易维护,那么考虑从外向里缩,首先我们假设把矩形的最外圈当作边界,这个里头的水,肯定不能超过外圈中最低的那个格子,那么从最低的格子往内bfs。

        1.  如果这个格子比之前的低,那么可以边界就会往里存水,入队的时候高度要设置成存水后的高度。

         2. 如果这个格子比边界高,那么存不住水,直接更新边界就可以。

       如何选取边界最低的呢,用一个优先队列,维护外层格子的高低。

复杂度O(n*n*log (n*n) )

struct node
{
    int x,y,h;
    node(){}
    node(int a,int b,int c){
        x = a;y =b;h = c;
    }
    bool operator < (const node r)const{
        return h > r.h; 
    }
};
class Solution {
public:
    int vis[116][116];
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    priority_queue<node>q;
    int trapRainWater(vector<vector<int>>& heightMap) {
        int n = heightMap.size();
        if(n <= 1)return 0;
        int m = heightMap[0].size();
        if(m <= 1)return 0;
        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)
                    vis[i][j] =1,
                    q.push(node(i,j,heightMap[i][j]));
            }
        }
        int cnt = 0;
        while(q.size()){
            node x = q.top();
            q.pop();
            for(int i=0;i<4;i++){
                int xx = x.x+dx[i];
                int yy = x.y+dy[i];
                if(xx>=0 && xx<n&&yy>=0&&yy<m && !vis[xx][yy]){
                    vis[xx][yy] = 1;
                    if(heightMap[xx][yy] > x.h){
                        q.push(node(xx,yy,heightMap[xx][yy]));
                    }
                    else{
                        cnt += x.h - heightMap[xx][yy];
                        q.push(node(xx,yy,x.h));
                    }
                }
            }
        }
        return cnt;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_41645482/article/details/105971196