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. Note: Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000. 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.
https://leetcode.com/problems/trapping-rain-water-ii/discuss/89461/Java-solution-using-PriorityQueue https://www.youtube.com/watch?v=cJayBq38VYw class Solution { public int trapRainWater(int[][] heightMap) { if (heightMap == null || heightMap.length <= 1 || heightMap[0].length <= 1) { return 0; } int m = heightMap.length; int n = heightMap[0].length; boolean[][] visited = new boolean[m][n]; // priority queue store the cell in format of [row, col, height] PriorityQueue<int[]> q = new PriorityQueue<>((c1, c2) -> c1[2] - c2[2]); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i == 0 || j == 0 || i == m - 1 || j == n - 1) { visited[i][j] = true; q.offer(new int[]{i, j, heightMap[i][j]}); } } } // bfs from outside int res = 0; int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; while (!q.isEmpty()) { int[] cell = q.poll(); for (int[] dir : dirs) { int x = cell[0] + dir[0]; int y = cell[1] + dir[1]; if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) { visited[x][y] = true; res += Math.max(0, cell[2] - heightMap[x][y]); q.offer(new int[]{x, y, Math.max(cell[2], heightMap[x][y])}); } } } return res; } }