接雨水
双指针法:
public int trap(int[] height) {
//双指针,分别计算每一个水柱的左侧高度最大值和右侧高度最大值
int []leftHeight=new int[height.length];
int []rightHeight=new int[height.length];
leftHeight[0]=height[0];
rightHeight[height.length-1]=height[height.length-1];
for(int i=1;i<height.length;i++){
leftHeight[i]=Math.max(leftHeight[i-1],height[i]);
}
for(int i=height.length-2;i>=0;i--){
rightHeight[i]=Math.max(rightHeight[i+1],height[i]);
}
int res=0;
for(int i=1;i<height.length-1;i++){
int rain=Math.min(leftHeight[i],rightHeight[i])-height[i];
if(rain>0)res+=rain;
}
return res;
}
}
单调栈法
public int trap(int[] height) {
int size = height.length;
if (size <= 2) return 0;
int res=0;
Deque<Integer> stack=new LinkedList<>();
stack.push(0);
for(int i=1;i<height.length;i++){
if(height[i]<height[stack.peek()]){
stack.push(i);
}else if(height[i]==height[stack.peek()]){
stack.pop();
stack.push(i);
}else{
while(!stack.isEmpty()&&height[i]>height[stack.peek()]){
int index=stack.pop();
if(!stack.isEmpty()){
int h=Math.min(height[i],height[stack.peek()])-height[index];
int w=i-stack.peek()-1;
res+=h*w;
}
}
stack.push(i);
}
}
return res;
}
84.柱状图中最大的矩形
双指针
public int largestRectangleArea(int[] heights) {
int[]leftIndex=new int[heights.length];
int[]rightIndex=new int[heights.length];
leftIndex[0]=-1;
rightIndex[heights.length-1]=heights.length;
for(int i=1;i<heights.length;i++){
int left=i-1;
while(left>=0&&heights[left]>=heights[i])left=leftIndex[left];
leftIndex[i]=left;
}
for(int i=heights.length-2;i>=0;i--){
int right=i+1;
while(right<=heights.length-1&&heights[right]>=heights[i])right=rightIndex[right];
rightIndex[i]=right;
}
int res=0;
for(int i=0;i<heights.length;i++){
int sum=heights[i]*(rightIndex[i]-leftIndex[i]-1);
res=Math.max(res,sum);
}
return res;
}