407. Trapping Rain Water II

问题:

给定二维数组,表示各个位置上建筑的高度。

求下雨累计雨量最多为多少?

Example:
Given the following 3x6 height map:
[
  [1,4,3,1,3,2],
  [3,2,1,3,2,4],
  [2,3,3,2,3,1]
]

Return 4.
The above image represents the elevation map [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.
After the rain, water is trapped between the blocks. The total volume of water trapped is 4.

Constraints:
1 <= m, n <= 110
0 <= heightMap[i][j] <= 20000

 

 

 解法:BFS

使用优先队列priority_queue,使得每次能弹出queue中的最小值

1 priority_queue<vector<int>, vector<vector<int>>, cmp> q;
2 //vector<int>:每个元素类型
3 //vector<vector<int>>:queue的存储类型
4 //cmp:类cmp,重载operator() 方法

class cmp:

1 class cmp {
2 public:
3     bool operator()(const vector<int>& a, const vector<int>& b) {
4         return a[0]>b[0];//10,9,8...1 return 1
5     }
6 };

 

 优先队列:

  • 默认最大堆,less:从小到大排序,返回最后一个数(最大值) 函数体:return para_1 < para_2
  • greater:从大到小排序,返回最后一个数(最小值) 函数体:return para_1 > para_2
//默认是大顶堆 {5,4,3,2,1}
priority_queue<int> a; 
priority_queue<int, vector<int>, less<int> > a;
 
//小顶堆 {1,2,3,4,5}priority_queue<int, vector<int>, greater<int> > c;

unordered_set<type>

  • 当使用unordered_set判断visited的时候,由于需要用到insert方法和count,判断是否已经存在某个type的元素。
  • 要用到type元素的比较方法,
  • 一般的,我们直接将需要的类型转化为string,直接使用unordered_set<string>即可。(不需要再实现==比较方法)

 

对于本问题:

思想参考:leetcode讨论

  1. 首先将四周边缘存入queue中,(可看作存水围墙)
  2. for all queue element:
    1. 取得最小高度的cell:cur,为当前雨水高度Waterlevel(水围墙的最低高度为,当前最高水位)
    2. 对cur遍历四周:(不在水围墙上(visited[x][y]!=1)只可能是水位墙内部,因此一定能冲入水)
    3. 若存在高度<当前水位Waterlevel的cell,将这个位置的水位差加入res
    4. 对cur四周的节点,都遍历过,visited设为1,同时加入queue(水围墙被向内缩小,更新)Loop->2

 

代码参考:

 1 class cmp {
 2 public:
 3     bool operator()(const vector<int>& a, const vector<int>& b) {
 4         return a[0]>b[0];//10,9,8...1 return 1
 5     }
 6 };
 7 class Solution {
 8 public:
 9     int trapRainWater(vector<vector<int>>& heightMap) {
10         int res=0;
11         priority_queue<vector<int>, vector<vector<int>>, cmp> q;
12         int n = heightMap.size();
13         int m = heightMap[0].size();
14         vector<vector<int>> visited(n, vector<int>(m, 0));
15         vector<vector<int>> dir({{1,0},{-1,0},{0,1},{0,-1}});
16         //add boarder into queue
17         for(int i=0; i<n; i++) {
18             q.push({heightMap[i][0],i,0});
19             q.push({heightMap[i][m-1],i,m-1});
20             visited[i][0] = 1;
21             visited[i][m-1] = 1;
22         }
23         for(int j=0; j<m; j++) {
24             if(visited[0][j]!=1) q.push({heightMap[0][j],0,j});
25             if(visited[n-1][j]!=1) q.push({heightMap[n-1][j],n-1,j});
26             visited[0][j] = 1;
27             visited[n-1][j] = 1;
28         }
29         int Waterlevel = INT_MIN;
30         while(!q.empty()) {
31             //get min cell of queue
32             vector<int> cur = q.top();
33             q.pop();
34             Waterlevel = max(Waterlevel,cur[0]);
35            // cout<<Waterlevel<<endl;
36             for(vector<int> d:dir) {
37                 int x = cur[1]+d[0], y = cur[2]+d[1];
38                 if(x<=0 || y<=0 || x>=n-1 || y>=m-1 || visited[x][y] == 1) continue;
39                 if(heightMap[x][y]<Waterlevel) res+=(Waterlevel-heightMap[x][y]);
40                 q.push({heightMap[x][y], x, y});
41                 visited[x][y] = 1;
42             }
43         }
44         return res;
45     }
46 };

 

  

 

posted @ 2021-02-27 13:15  habibah_chang  阅读(51)  评论(0编辑  收藏  举报