往高低不平的一堆相连的方柱注水,问最多能保持住多少水。是之前Trapping Rain Water I拓展到二维的情况,但解法并不只是对每个格子横竖都检查一遍就可以了,因为(i, j)能蓄多少水取决于j列能蓄多少水,而j列能蓄多少又取决于([0, i -1], j),相互之间形成了dependency。虽然不能直接套用一维的解法,但基本原则是一样的:1. 每块能蓄多少水是由它(即使隔的很远)最高的一圈外围决定的;2. 又取决于那圈外围中最矮的高度。因此模拟不断增加高度从外往内漫水的过程,从最外层开始做BFS,维持一个global变量记录当前遍历过的最高高度mx。每次找Q中高度最小的块抛出并更新最高高度mx,模拟水位到了mx的情况,mx也就是外围中最矮高度。遍历它前后左右并压入Q做候选,如果邻居中找到了比当前块还低的块,意味着水位mx - height(neighbor)就是neighbor能蓄的水量。
/* * @lc app=leetcode id=407 lang=cpp * * [407] Trapping Rain Water II */// @lc code=startclassSolution {public:inttrapRainWater(vector<vector<int>>& heightMap) {if (heightMap.empty()) return0;constint M =heightMap.size(), N =heightMap[0].size(); // min heap priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q; vector<vector<bool>>visited(M,vector<bool>(N,false)); vector<vector<int>> dirs{{-1,0}, {1,0}, {0,-1}, {0,1}};for (int i =0; i < M; ++i) {for (int j =0; j < N; ++j) {if (i ==0|| i == M -1|| j ==0|| j == N -1) {q.push({heightMap[i][j], i * N + j});visited[i][j] =true; } } }int mx =0, res =0;while (!q.empty()) {constauto t =q.top(); q.pop();constauto h =t.first, i =t.second / N, j =t.second % N; mx =max(mx, h);for (constauto&d : dirs) {constint x = i +d[0], y = j +d[1];if (x >=0&& x < M && y >=0&& y < N &&!visited[x][y]) {visited[x][y] =true;if (heightMap[x][y] < mx) res += mx -heightMap[x][y];q.push({heightMap[x][y], x * N + y}); } } }return res; }};// @lc code=end