Trapping rain water II
public class Solution {
/**
* @param heights: a matrix of integers
* @return: an integer
*/
int[] dx = new int[] {-1,1,0,0};
int[] dy = new int[] {0,0,1,-1};
public int trapRainWater(int[][] heights) {
// null check
if(heights == null || heights.length == 0)
return 0;
// min heap
Queue<Cell> pq = new PriorityQueue<Cell>(1, new Comparator<Cell>() {
public int compare(Cell c1, Cell c2) {
return c1.h - c2.h;
}
});
int m = heights.length;
int n = heights[0].length;
// record if visited
boolean[][] visited = new boolean[m][n];
// add all cells at edage into pq
for (int i = 0; i < m; i++) {
pq.offer(new Cell(i,0,heights[i][0]));
pq.offer(new Cell(i,n-1,heights[i][n-1]));
visited[i][0] = true;
visited[i][n-1] = true;
}
for (int i = 0; i < n; i++) {
pq.offer(new Cell(0,i,heights[0][i]));
pq.offer(new Cell(m-1,i,heights[m-1][i]));
visited[0][i] = true;
visited[m-1][i] = true;
}
int res = 0 ;
// use pq to find min height each time
// and then get water for at most 4 cells for cur cell
while(!pq.isEmpty()) {
Cell now = pq.poll();
for(int i = 0; i < 4; i++) {
int nx = now.x + dx[i];
int ny = now.y + dy[i];
if(0 <= nx && nx < m && 0 <= ny && ny < n && !visited[nx][ny]) {
visited[nx][ny] = true;
pq.offer(new Cell(nx,ny,Math.max(now.h,heights[nx][ny])));
res += Math.max(0, now.h - heights[nx][ny]);
}
}
}
return res;
}
// needs a DS
class Cell {
int x, y, h;
public Cell(int x, int y, int h) {
this.x = x;
this.y = y;
this.h = h;
}
}
};