Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.
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
classSolution {// https://drive.google.com/file/d/1YHHlkHkx5Ae9Ft9dAHMV52HMnOCnYcMF/view?usp=sharingstaticclassPair {int x, y, val;Pair(int x,int y,int v) {this.x= x;this.y= y;this.val= v; } }publicinttrapRainWater(int[][] heightMap) {int m =heightMap.length, n = heightMap[0].length;if (m ==1|| n ==1)return0;// Priority Queue hold virtual border which holds water inside// Therefore starting border is border of matrixPriorityQueue<Pair> pq =newPriorityQueue<>((a, b) ->a.val-b.val);boolean[][] visited =newboolean[m][n];for (int i =0; i < m; i++) {pq.add(newPair(i,0, heightMap[i][0])); visited[i][0] =true;pq.add(newPair(i, n -1, heightMap[i][n -1])); visited[i][n -1] =true; }for (int i =1; i < n -1; i++) {pq.add(newPair(0, i, heightMap[0][i])); visited[0][i] =true;pq.add(newPair(m -1, i, heightMap[m -1][i])); visited[m -1][i] =true; }// Now we want to find smallest height, and check all unvisited neighbors// If any neighbor < border height(min), then we can add this water to our// answer, as it cannot flow out of border from any directionint[][] dirs = { { 1,0 }, { 0,1 }, { -1,0 }, { 0,-1 } };int ans =0;while (pq.size() !=0) {Pair smallest =pq.poll();int x =smallest.x, y =smallest.y;for (int[] dir : dirs) {int newX = x + dir[0], newY = y + dir[1];if (newX >=0&& newX < m && newY >=0&& newY < n &&!visited[newX][newY]) { visited[newX][newY] =true;// If we can store some water here, then this stored water// will also work as a wall in our virtual borderif (heightMap[newX][newY] <smallest.val) { ans +=smallest.val- heightMap[newX][newY];pq.add(newPair(newX, newY,smallest.val)); } elsepq.add(newPair(newX, newY, heightMap[newX][newY])); } } }return ans; }}