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讨论
- 首先将四周边缘存入queue中,(可看作存水围墙)
- for all queue element:
- 取得最小高度的cell:cur,为当前雨水高度Waterlevel(水围墙的最低高度为,当前最高水位)
- 对cur遍历四周:(不在水围墙上(visited[x][y]!=1)只可能是水位墙内部,因此一定能冲入水)
- 若存在高度<当前水位Waterlevel的cell,将这个位置的水位差加入res
- 对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 };