二维数组存储的是每个单元的高度,求最多接多少体积的雨水
首先想到的就是找到最低点
注意看后两个图,当水超过3的时候,可以从绿的的点流进内部
所以可以想象内部现在的水的高度可以达到3,减去原来的体积,就是水的体积
太机智了吧
这个就是想象,想象水流进来的感觉,从内部往外面扩展,找不到什么规律
要注意的一点就是,四周的点是没什么用的,因为首先积水肯定不会在四周
然后内部有积水后,将数组中的高度重新赋值为当前积水高度
public class Solution {
public class Cell {
int row;
int col;
int height;
public Cell(int row, int col, int height) {
this.row = row;
this.col = col;
this.height = height;
}
}
public int trapRainWater(int[][] heights) {
if (heights == null || heights.length == 0 || heights[0].length == 0)
return 0;
PriorityQueue<Cell> queue = new PriorityQueue<>(1, new Comparator<Cell>(){
public int compare(Cell a, Cell b) {
return a.height - b.height;
}
});
int m = heights.length;
int n = heights[0].length;
boolean[][] visited = new boolean[m][n];
// Initially, add all the Cells which are on borders to the queue.
for (int i = 0; i < m; i++) {
visited[i][0] = true;
visited[i][n - 1] = true;
queue.offer(new Cell(i, 0, heights[i][0]));
queue.offer(new Cell(i, n - 1, heights[i][n - 1]));
}
for (int i = 0; i < n; i++) {
visited[0][i] = true;
visited[m - 1][i] = true;
queue.offer(new Cell(0, i, heights[0][i]));
queue.offer(new Cell(m - 1, i, heights[m - 1][i]));
}
// from the borders, pick the shortest cell visited and check its neighbors:
// if the neighbor is shorter, collect the water it can trap and update its height as its height plus the water trapped
// add all its neighbors to the queue.
int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int res = 0;
while (!queue.isEmpty()) {
Cell cell = queue.poll();
for (int[] dir : dirs) {
int row = cell.row + dir[0];
int col = cell.col + dir[1];
if (row >= 0 && row < m && col >= 0 && col < n && !visited[row][col]) {
visited[row][col] = true;
res += Math.max(0, cell.height - heights[row][col]);
queue.offer(new Cell(row, col, Math.max(heights[row][col], cell.height)));
}
}
}
return res;
}
}
太难了,所以看得网上大神做的复制过来
大神厉害,自定义一个cell结构
创建具有 PriorityQueue初始容量的PriorityQueue,根据指定的比较器对其元素进行排序。
值得注意的是,优先级队列的默认排序是数值大的优先级高,排在前面,所以我们需要重写排序函数