模式识别:求雨水的面积 ——> 不仅是只求一个比当前元素大的元素,还要求面积
单调栈
单调栈实现
单调栈的维护
int mid = st.top();
st.pop();
int h = Math.min(st.top(),height[i])-height[mid];
从右侧柱高,和左侧柱高取个最小值int width = i - st.pop() - 1;
area = h * width;
class Solution {
public int trap(int[] height) {
int sum = 0;
if(height.length == 0){
return 0;
}
// 定义栈
Stack<Integer> st = new Stack<Integer>();
st.push(0);
for(int i = 1 ; i < height.length;i++){
if(height[i] <= height[st.peek()]){
st.push(i);
}else{
while(!st.isEmpty() && height[i] > height[st.peek()]){
int mid = st.peek();
st.pop();
if(!st.isEmpty()){
int h = Math.min(height[st.peek()],height[i]) - height[mid];
int width = i-st.peek() - 1;
int hold = h*width;
sum+=hold;
}
}
st.push(i);
}
}
return sum;
}
}
public class getRain {
public static int getRain(int[] nums){
// 定义单调栈
int len = nums.length;
if(len==0){
return 0;
}
int sum = 0;
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 1 ; i < len;i++){
if(nums[i]<=nums[st.peek()]){
st.push(i);
}else{
while(!st.isEmpty() && nums[i] > nums[st.peek()]){
int mid = st.peek();
st.pop();
if(!st.isEmpty()){
int h = Math.min(nums[st.peek()],nums[i])-nums[mid];
int width = i - st.peek()-1;
int hold = h*width;
sum+=hold;
}
}
}
st.push(i);
}
return sum;
}
public static void main(String[] args) {
// 计算
Scanner sc = new Scanner(System.in);
System.out.println("输入数组长度");
int n = sc.nextInt();
int[] nums = new int[n];
for(int i = 0 ; i < n ; i ++){
nums[i] = sc.nextInt();
}
System.out.println("雨水面积是"+getRain(nums));
}
}