思维+木桶理论+最小堆——leetcode407
接雨水的二维版,先把最外层的边框围起来,然后逐步向内收缩边框,每次找边框的最低点,然后内(四个方向拓展)
如何统计每个点的贡献?由于木桶理论,该木桶内水的高度等于木桶边框的最低点,那么拓展时如果遇到边框小于当前边框,说明这个位置可以灌水,同时这个位置的高度也可以改成当前边框的高度
class Solution { public: struct Node{ int i,j,h; Node(){} bool operator>(const Node a)const { return h>a.h; } }; int n,m,vis[200][200]; priority_queue<Node,vector<Node>,greater<Node> >pq; int trapRainWater(vector<vector<int>>& heightMap) { if(heightMap.size()==0)return 0; if(heightMap[0].size()==0)return 0; n=heightMap.size(); m=heightMap[0].size(); memset(vis,0,sizeof vis); for(int j=0;j<m;j++){ Node t; t.i=0,t.j=j,t.h=heightMap[0][j]; pq.push(t); t.i=n-1,t.j=j,t.h=heightMap[n-1][j]; pq.push(t); vis[0][j]=vis[n-1][j]=1; } for(int i=1;i<n-1;i++){ Node t; t.i=i,t.j=0,t.h=heightMap[i][0]; pq.push(t); t.i=i,t.j=m-1,t.h=heightMap[i][m-1]; pq.push(t); vis[i][0]=vis[i][m-1]=1; } int sum=0; while(pq.size()){ Node now=pq.top();pq.pop(); int i=now.i,j=now.j,h=now.h; sum+=h-heightMap[i][j]; //cout<<i<<" "<<j<<" "<<h<<"\n"; if(i-1>=0 && vis[i-1][j]==0){ Node t; t.i=i-1,t.j=j,t.h=max(h,heightMap[i-1][j]); pq.push(t); vis[i-1][j]=1; } if(i+1<n && vis[i+1][j]==0){ Node t; t.i=i+1,t.j=j,t.h=max(h,heightMap[i+1][j]); pq.push(t); vis[i+1][j]=1; } if(j-1>=0 && vis[i][j-1]==0){ Node t; t.i=i,t.j=j-1,t.h=max(h,heightMap[i][j-1]); pq.push(t); vis[i][j-1]=1; } if(j+1<m && vis[i][j+1]==0){ Node t; t.i=i,t.j=j+1,t.h=max(h,heightMap[i][j+1]); pq.push(t); vis[i][j+1]=1; } } return sum; } };