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.
思路:与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 }