Problem 6 Trapping Rain Water II
这道题最坑的部分是,一个是高度,一个是它这个点的蓄水高度
(普及)高度是给里面点的蓄水高度准备的
蓄水高度是根据周围的点的(普及高度)高度来说
关键点
普及高度,只可能升高,不可能变低
走的点是从最小的普及高度,
蓄水量 = max(普及高度 - 该点的高度,0)
generate 要做什么
计算neighbor的蓄水量
蓄水量 = max(cur.普及高度 - neighbor.高度,0)
update到neighbor为止的普及高度
cost 就是普及高度 ,所以neighbor.普及高度 = max (cur.普及高度, neighbor的高度) (since cur.普及高度>0) = cur.普及高度 + max(0, neighbor.高度 - cur.普及高度)
cost 就是普及高度
cost(开始的点(外围一圈最小点), x.neighbor) = cost(开始的点, x) + cost (x, neighbor)
所以edge上的weight应该是这玩意 max(0, neighbor的高度 - cur.普及高度)
class Solution {
class Element implements Comparable<Element> {
int x;
int y;
int pujiHeight;
public Element(int x, int y, int pujiHeight) {
this.x = x;
this.y = y;
this.pujiHeight = pujiHeight;
}
@Override
public int compareTo(Element other) {
return Integer.compare(this.pujiHeight, other.pujiHeight);
}
}
public int trapRainWater(int[][] heightMap) {
// sanity check
if (heightMap == null || heightMap.length == 0 || heightMap[0].length == 0) {
return -1;
}
// initiation (result, graph, visited, minHeap, etc)
int[] result = new int[]{0};
boolean[][] visited = new boolean[heightMap.length][heightMap[0].length];
PriorityQueue<Element> minHeap = new PriorityQueue<>();
// bfs
bfs(minHeap, heightMap, visited, result);
// return result
return result[0];
}
private static final int[][] dirs = new int[][]{{-1, 0}, {1,0}, {0, 1}, {0, -1}};
private void bfs(PriorityQueue<Element> minHeap, int[][] heightMap, boolean[][] visited, int[] result) {
// initial state
initialState(minHeap, heightMap, visited);
while (!minHeap.isEmpty()) {
Element cur = minHeap.poll();
for (int[] dir : dirs) {
int neiX = cur.x + dir[0];
int neiY = cur.y + dir[1];
if (isValid(heightMap, neiX, neiY) && !visited[neiX][neiY]) {
int cost = Math.max(cur.pujiHeight - heightMap[neiX][neiY], 0);
result[0] += cost;
int neiPujiHeight = cur.pujiHeight + Math.max(heightMap[neiX][neiY] - cur.pujiHeight, 0);
Element neiElement = new Element(neiX, neiY, neiPujiHeight);
minHeap.offer(neiElement);
visited[neiX][neiY] = true;
}
}
}
}
private void initialState(PriorityQueue<Element> minHeap, int[][] heightMap, boolean[][] visited) {
// add the top and bottom row
for (int i = 0; i < heightMap[0].length; i++) {
minHeap.offer(new Element(0, i, heightMap[0][i]));
minHeap.offer(new Element(heightMap.length - 1, i, heightMap[heightMap.length - 1][i]));
visited[0][i] = true;
visited[heightMap.length - 1][i] = true;
}
// add the left and right column
for (int j = 0; j < heightMap.length; j++) {
minHeap.offer(new Element(j, 0, heightMap[j][0]));
minHeap.offer(new Element(j, heightMap[0].length - 1, heightMap[j][heightMap[0].length - 1]));
visited[j][0] = true;
visited[j][heightMap[0].length - 1] = true;
}
}
private boolean isValid(int[][] heightMap, int x, int y) {
return x >= 0 && x < heightMap.length && y >= 0 && y < heightMap[0].length;
}
}
Last updated