Trapping Rain Water II Leetcode
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.
这道题才算hard,看着就让人眼晕的那种。。。代码的确改了半天,思路比较清晰但不是这里忘记就是那里忘记。。。而且写的挺丑的。
需要注意的点有:
每次算出这个点能装水,不要忘记把本个点放到heap里同时要把本个点标记为已经访问过了。
每次放heap里面放点的时候,如果当前点小于桶边的点,要放当前点的坐标,桶边点的高度,因为是按照最高高度装水的。
public class Solution { public int trapRainWater(int[][] heightMap) { if (heightMap == null || heightMap.length == 0) { return 0; } int m = heightMap.length; int n = heightMap[0].length; int[][] visited = new int[m][n]; int count = 0; PriorityQueue<Cell> pq = new PriorityQueue<>(new CellComparator()); for (int i = 0; i < heightMap.length; i++) { Cell c = new Cell(i, 0, heightMap[i][0]); Cell d = new Cell(i, heightMap[i].length - 1, heightMap[i][heightMap[i].length - 1]); pq.offer(c); pq.offer(d); visited[i][0] = 1; visited[i][heightMap[i].length - 1] = 1; } for (int i = 0; i < heightMap[0].length; i++) { Cell c = new Cell(0, i, heightMap[0][i]); Cell d = new Cell(heightMap.length - 1, i, heightMap[heightMap.length - 1][i]); pq.offer(c); pq.offer(d); visited[0][i] = 1; visited[heightMap.length - 1][i] = 1; } while (!pq.isEmpty()) { Cell c = (Cell) pq.poll(); if (c.x - 1 >= 0 && visited[c.x - 1][c.y] != 1) { Cell nc = null; if (heightMap[c.x - 1][c.y] >= c.value) { nc = new Cell(c.x - 1, c.y, heightMap[c.x - 1][c.y]); } else { count += c.value - heightMap[c.x - 1][c.y]; nc = new Cell(c.x - 1, c.y, c.value); } pq.offer(nc); visited[c.x - 1][c.y] = 1; } if (c.x + 1 < m && visited[c.x + 1][c.y] != 1) { Cell nc = null; if (heightMap[c.x + 1][c.y] >= c.value) { nc = new Cell(c.x + 1, c.y, heightMap[c.x + 1][c.y]); } else { count += c.value - heightMap[c.x + 1][c.y]; nc = new Cell(c.x + 1, c.y, c.value); } pq.offer(nc); visited[c.x + 1][c.y] = 1; } if (c.y - 1 >= 0 && visited[c.x][c.y - 1] != 1) { Cell nc = null; if (heightMap[c.x][c.y - 1] >= c.value) { nc = new Cell(c.x, c.y - 1, heightMap[c.x][c.y - 1]); } else { count += c.value - heightMap[c.x][c.y - 1]; nc = new Cell(c.x, c.y - 1, c.value); } pq.offer(nc); visited[c.x][c.y - 1] = 1; } if (c.y + 1 < n && visited[c.x][c.y + 1] != 1) { Cell nc = null; if (heightMap[c.x][c.y + 1] >= c.value) { nc = new Cell(c.x, c.y + 1, heightMap[c.x][c.y + 1]); } else { count += c.value - heightMap[c.x][c.y + 1]; nc = new Cell(c.x, c.y + 1, c.value); } pq.offer(nc); visited[c.x][c.y + 1] = 1; } } return count; } class Cell { int x; int y; int value; Cell(int x, int y, int value) { this.x = x; this.y = y; this.value = value; } } class CellComparator implements Comparator<Cell> { public int compare(Cell a, Cell b) { return a.value - b.value; } } }
然后对照了一下人家的代码。。。又高下立现了。。。= =不过我没用过这个技巧情有可原嘛,以后就会了哈哈哈
改良后的版本:
public class Solution { public int trapRainWater(int[][] heightMap) { if (heightMap == null || heightMap.length == 0) { return 0; } int m = heightMap.length; int n = heightMap[0].length; int[][] visited = new int[m][n]; int count = 0; PriorityQueue<Cell> pq = new PriorityQueue<>(new CellComparator()); for (int i = 0; i < m; i++) { pq.offer(new Cell(i, 0, heightMap[i][0])); pq.offer(new Cell(i, n - 1, heightMap[i][n - 1])); visited[i][0] = 1; visited[i][n - 1] = 1; } for (int i = 0; i < n; i++) { pq.offer(new Cell(0, i, heightMap[0][i])); pq.offer(new Cell(m - 1, i, heightMap[m - 1][i])); visited[0][i] = 1; visited[m - 1][i] = 1; } int[][] nei = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; while (!pq.isEmpty()) { Cell c = pq.poll(); for (int[] cor : nei) { int row = c.x + cor[0]; int col = c.y + cor[1]; if (row >=0 && row < m && col >= 0 && col < n && visited[row][col] != 1) { pq.offer(new Cell(row, col, Math.max(heightMap[row][col], c.value))); count += Math.max(0, c.value - heightMap[row][col]); visited[row][col] = 1; } } } return count; } class Cell { int x; int y; int value; Cell(int x, int y, int value) { this.x = x; this.y = y; this.value = value; } } class CellComparator implements Comparator<Cell> { public int compare(Cell a, Cell b) { return a.value - b.value; } } }