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.
Java代码:
public class Solution {
public static class node{
int row;
int clomm;
int h;
node(int row,int clomn,int h){
this.row=row;
this.clomm=clomn;
this.h=h;
}
}
public static int trapRainWater(int[][] heightMap) {
if(heightMap.length==0)return 0;
int[][] h=heightMap;
boolean[][] visit=new boolean[heightMap.length][heightMap[0].length];
Queue<node> que=new PriorityQueue<node>(new Comparator<node>(){
public int compare(node a,node b){
return a.h-b.h;
}
});
int m=heightMap.length;
int n=heightMap[0].length;
for(int i=0;i<n;i++){
que.add(new node(0,i,h[0][i]));
visit[0][i]=true;
que.add(new node(m-1,i,h[m-1][i]));
visit[m-1][i]=true;
}
for(int i=0;i<m;i++){
que.add(new node(i,0,h[i][0]));
visit[i][0]=true;
que.add(new node(i,n-1,h[i][n-1]));
visit[i][n-1]=true;
}
int water=0;
int[][] f={{1,0},{-1,0},{0,1},{0,-1}};
while(!que.isEmpty()){
node cur=que.poll();
for(int[] ff:f){
int newr=cur.row+ff[0];
int newc=cur.clomm+ff[1];
if(newr<0||newr>=m||newc<0||newc>=n||visit[newr][newc])continue;
visit[newr][newc]=true;
water+=Math.max(0,cur.h-h[newr][newc]);
que.add(new node(newr,newc,Math.max(h[newr][newc],cur.h)));
}
}
return water;
}
}
时间复杂度:O(N*M)
思路:
通过四周的围墙去向中心注水,采用优先级队列(Java优先级队列采用的是最小堆实现的),队列头的元素是四周高度最小的,这样额可以保证向四周注入的水不溢出,同时也保证了其向四周可以注入的最大水的高度,即便不能注入水也能保证,下一个四周元素可以进入队列而被计算。