首页 > 代码库 > Leetcode 407. Trapping Rain Water II

Leetcode 407. 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.

标签 Breadth-first Search Heap
类似题目 (H) Trapping Rain Water
 

 

 

思路:与2D的管住两边的最低高度,3D只要管住包围的环中的最低高度就可以,保证最外围的单元一定在优先队列中,然后每次先遍历原先队列中高度最小的单元A,如果A的四周有尚未被遍历并且高度小于A的单元B,那么A的高度-B的高度就是新增加的蓄水体积,然后设置B的高度=max(A的高度,B的高度),将B加入优先队列。

另外一个需要注意的是解法中对类的比较的定义,Cell执行Comparable借口,重定义compareTo(Cell o)函数:返回负数意味着当前元素“小于”o,返回正数意味着当前元素“大于”o,返回0意味着当前元素“等于”o。

compareTo函数中定义成:

return this.height - o.height;

这就意味着this.height > o.height时,Comparable返回的是当前元素“大于”o;this.height < o.height时,Comparable返回的是当前元素“小于”o。又因为JAVA的PriorityQueue是小顶堆,因此队列的Cell是按height升序排列的。

那么,如果想要队列中的Cell按height降序排列,又可以怎么写? 

compareTo函数中可以定义成这样:

return o.height - this.height;

这就意味着如果this.height > o.height时,Comparable返回的是当前元素“小于”o,又因为JAVA的PriorityQueue是小顶堆,因此队列的当前元素排在o之前,也就是队列是按降序排列的。

 

代码:

 1 public class Solution {
 2      class Cell implements Comparable<Cell> {
 3         int row, col, height;
 4         public Cell(int row, int col, int height) {
 5             this.row = row;
 6             this.col = col;
 7             this.height = height;
 8         }
 9         //返回负数意味着当前元素“小于”o,返回正数意味着当前元素“大于”o,返回0意味着当前元素“等于”o
10         //JAVA中PriorityQueue默认的是小顶堆
11         public int compareTo(Cell o) {
12             return this.height - o.height;
13         }
14     }
15     
16     public int trapRainWater(int[][] heightMap) {
17         int n = heightMap.length, m = heightMap[0].length, res = 0;
18         int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
19         boolean[][] visited = new boolean[n][m];
20         PriorityQueue<Cell> queue = new PriorityQueue<Cell>();
21         for (int i = 0; i < n; ++i) {
22             visited[i][0] = visited[i][m - 1] = true;
23             queue.offer(new Cell(i, 0, heightMap[i][0]));
24             queue.offer(new Cell(i, m - 1, heightMap[i][m - 1]));
25         }
26         for (int i = 0; i < m; ++i) {
27             visited[0][i] = visited[n - 1][i] = true;
28             queue.offer(new Cell(0, i, heightMap[0][i]));
29             queue.offer(new Cell(n - 1, i, heightMap[n - 1][i]));
30         }
31         while (!queue.isEmpty()) {
32             Cell cell = queue.poll();
33             for (int i = 0; i < 4; ++i) {
34                 for (int j = 0; j < 2; ++j) {
35                     int row = cell.row + dirs[i][j];
36                     int col = cell.col + dirs[i][j];
37                     if (row > 0 && row < n && col > 0 && col < m && !visited[row][col]) {
38                         res += Math.max(0, cell.height - heightMap[row][col]);
39                         queue.offer(new Cell(row, col, Math.max(cell.height, heightMap[row][col])));
40                     }
41                 }
42             }
43         }
44         return res;
45     }
46 }

 

Leetcode 407. Trapping Rain Water II