题目:
https://leetcode-cn.com/problems/trapping-rain-water-ii/
import java.util.Comparator;
import java.util.PriorityQueue;
public class _407_TrapRainWater {
public class Location {
int row, col, height;
public Location(int row, int col, int height) {
this.row = row;
this.col = col;
this.height = height;
}
}
public int trapRainWater(int[][] heightMap) {
int rows = heightMap.length;//宽
int cols = heightMap[0].length;//长
boolean[][] isResolve = new boolean[rows][cols];
//构造外围圈,初始化
PriorityQueue<Location> locations = new PriorityQueue<>(Comparator.comparingInt(x -> x.height));//堆里存的
for (int col = 0; col < cols; col++) {
locations.add(new Location(0, col, heightMap[0][col]));
isResolve[0][col] = true;
}
//第一列
for (int row = 1; row < rows - 1; row++) {
locations.add(new Location(row, 0, heightMap[row][0]));
isResolve[row][0] = true;
}
//最后一列
for (int row = 1; row < rows - 1; row++) {
locations.add(new Location(row, cols - 1, heightMap[row][cols - 1]));
isResolve[row][cols - 1] = true;
}
//最后一行
for (int col = 0; col < cols; col++) {
locations.add(new Location(rows - 1, col, heightMap[rows - 1][col]));
isResolve[rows - 1][col] = true;
}
//OK,开始找短板
int shortSlap = 0;
int waterAll = 0;
while (!locations.isEmpty()) {
Location curCircleShortSlap = locations.poll();
shortSlap = Math.max(shortSlap, curCircleShortSlap.height);//决出短板
//结算短板四周的水量
//左
int row = curCircleShortSlap.row;
int col = curCircleShortSlap.col;
if ((col - 1 >= 0) && (!isResolve[row][col - 1])) {
waterAll += Math.max(0, shortSlap - heightMap[row][col - 1]);//结算水量,用短板减去这里的地势,差值就是hold住的水
isResolve[row][col - 1] = true;
locations.add(new Location(row, col - 1, heightMap[row][col - 1]));//你该做边界了
}
//上
if ((row - 1 >= 0) && (!isResolve[row - 1][col])) {
waterAll += Math.max(0, shortSlap - heightMap[row - 1][col]);
isResolve[row - 1][col] = true;
locations.add(new Location(row - 1, col, heightMap[row - 1][col]));
}
//右
if ((col + 1 < cols) && (!isResolve[row][col + 1])) {
waterAll += Math.max(0, shortSlap - heightMap[row][col + 1]);
isResolve[row][col + 1] = true;
locations.add(new Location(row, col + 1, heightMap[row][col + 1]));
}
//下
if ((row + 1 < rows) && (!isResolve[row + 1][col])) {
waterAll += Math.max(0, shortSlap - heightMap[row + 1][col]);
isResolve[row + 1][col] = true;
locations.add(new Location(row + 1, col, heightMap[row + 1][col]));
}
}
return waterAll;
}
}