Leetcode: Trapping Rain Water II

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 are trapped between the blocks. The total volume of water trapped is 4.

Refer to https://discuss.leetcode.com/topic/60418/java-solution-using-priorityqueue/2

这里有具体的例子:http://www.cnblogs.com/grandyang/p/5928987.html

Analysis, 根据木桶原理,先找外围最矮的bar,里边如果有bar比它还矮,一定能存水(因为四周所有的bar都比它高)

注意还可能存更多的水,因为往里面,很可能cell高度变化。所以要把BFS中间遇到的高的bar都存进queue,随着水平面提升,提升到这些bar的高度,看能不能有凹槽存更多的水

44-45行逻辑就是

 if (height[row][col] < cur) {

  res += cur.height- height[row][col];

  queue.offer(new Cell(row, col, cur.height));

}

else {

  queue.offer(new Cell(row, col, height[row][col]));

}

 1 public class Solution {
 2     public class Cell {
 3         int row;
 4         int col;
 5         int height;
 6         public Cell(int x, int y, int val) {
 7             this.row = x;
 8             this.col = y;
 9             this.height = val;
10         }
11     }
12     
13     public int trapRainWater(int[][] heightMap) {
14         if (heightMap==null || heightMap.length<=2 || heightMap[0].length<=2) return 0;
15         int m = heightMap.length;
16         int n = heightMap[0].length;
17         int res = 0;
18         PriorityQueue<Cell> queue = new PriorityQueue<Cell>(1, new Comparator<Cell>() {
19             public int compare(Cell c1, Cell c2) {
20                 return c1.height - c2.height;
21             }
22         });
23         HashSet<Integer> visited = new HashSet<Integer>();
24         for (int i=0; i<m; i++) {
25             queue.offer(new Cell(i, 0, heightMap[i][0]));
26             queue.offer(new Cell(i, n-1, heightMap[i][n-1]));
27             visited.add(i*n+0);
28             visited.add(i*n+n-1);
29         }
30         for (int j=0; j<n; j++) {
31             queue.offer(new Cell(0, j, heightMap[0][j]));
32             queue.offer(new Cell(m-1, j, heightMap[m-1][j]));
33             visited.add(0*n+j);
34             visited.add((m-1)*n+j);
35         }
36         int[][] directions = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
37         while (!queue.isEmpty()) {
38             Cell cur = queue.poll();
39             for (int[] dir : directions) {
40                 int row = cur.row + dir[0];
41                 int col = cur.col + dir[1];
42                 if (row>=0 && row<m && col>=0 && col<n && !visited.contains(row*n+col)) {
43                     visited.add(row*n+col);
44                     res += Math.max(0, cur.height - heightMap[row][col]);
45                     queue.offer(new Cell(row, col, Math.max(cur.height, heightMap[row][col])));
46                 }
47             }
48         }
49         return res;
50     }
51 }
原文地址:https://www.cnblogs.com/EdwardLiu/p/6127893.html