双指针
- 根据木桶原理,储水量由最短边决定
- 我们使用两个指针,分别向左向右扫描,保存左右边的最高高度
- 如果
height[l] < height[r]
即右边高度高,则储水量由左边高度确定,反之相反
class Solution {
public:
int trap(vector<int>& height) {
int lmax=0,rmax=0;
int res = 0;
int l=0,r=height.size()-1;
while(l<=r){
if(height[l]<height[r]){
lmax = max(height[l],lmax);
res += lmax-height[l];
l++;
}else{
rmax = max(height[r],rmax);
res += rmax-height[r];
r--;
}
}
return res;
}
};
备忘录
- 遍历两次数组,分别记录每个位置 左右的最小木板高度
- 然后由
min(left,right)-height[i]
决定当前位置储水量
class Solution {
public:
int trap(vector<int>& height) {
int len = height.size();
vector<int> left(len),right(len);
for(int i=1;i<len;i++){
left[i] = max(left[i-1],height[i-1]);
}
for(int i=len-2;i>=0;i--){
right[i] = max(right[i+1],height[i+1]);
}
int res = 0;
for(int i=1;i<len-1;i++){
int level = min(left[i],right[i]);
res += max(0,level-height[i]);
}
return res;
}
};
栈保存
407 接雨水II
接雨水1,我们保存左右两边最小的木板高度,短边决定储水量
- 这个二维数组,我们则需要统计 四边的最短木板, 可以使用堆(优先队列)维护四边最短木板
- 然后由外围向内延伸,如果找到比当前队列中短边更小的位置,则可以储水,同时更新最短边高度
- 直到每个位置都访问完毕即可, 在遍历过程中,使用数组标记已访问,避免重复计算
class Solution {
public:
struct node{
int x,y,h;
node(int x,int y,int h):x(x),y(y),h(h){};
};
struct cmp{
bool operator ()(node* o1,node* o2){
return o1->h > o2->h;
}
};
int trapRainWater(vector<vector<int>>& heightMap) {
priority_queue<node*,vector<node*>,cmp> q;
if(heightMap.size() < 3|| heightMap[0].size()<3) return 0;
int row=heightMap.size(),col=heightMap[0].size();
vector<vector<bool>> dp(row,vector<bool>(col,false));
for(int i=0;i<row;i++){
q.push(new node(i,0,heightMap[i][0]));
dp[i][0]=true;
q.push(new node(i,col-1,heightMap[i][col-1]));
dp[i][col-1] = true;
}
for(int i=1;i<col-1;i++){
q.push(new node(0,i,heightMap[0][i]));
dp[0][i]=true;
q.push(new node(row-1,i,heightMap[row-1][i]));
dp[row-1][i]=true;
}
int res = 0;
int dirs[4][2] = {{1,0},{0,-1},{0,1},{-1,0} };
while(!q.empty()){
node* cur = q.top();
q.pop();
int x=cur->x;
int y=cur->y;
int h=cur->h;
for(int d=0;d<4;d++){
int nx=x+dirs[d][0];
int ny=y+dirs[d][1];
if(nx<0||nx>=row|| ny<0||ny>=col || dp[nx][ny]) continue;
if(h > heightMap[nx][ny]){
res += h-heightMap[nx][ny];
heightMap[nx][ny] = h;
}
q.push(new node(nx,ny,heightMap[nx][ny]));
dp[nx][ny] = true;
}
}
return res;
}
};
11. 盛最多水的容器
class Solution {
public:
int maxArea(vector<int>& height) {
int res = 0;
if(height.empty()) return res;
int l=0,r=height.size()-1;
while(l<r){
int level = min(height[l],height[r]);
res = max(res,level*(r-l));
if(height[r]>height[l]) l++;
else r--;
}
return res;
}
};