this problem is really classic

and we have a really classic way to solve this problem:
we iterate every value of given array, and each time, for a fixed value, we only consider the water it can contained, and we maintained two variables: leftMax and rightMax, those two variable only will update when it is necessary. and for a fixed value, the water it can contains is defined by the min(leftMax, rightMax).

class Solution {
    public int trap(int[] height) {
        
        int left = 0; //left指针和right指针的作用是标识 如果所有的坑都盛满,当前位置处的水的体积
        int right = height.length - 1;
        int res = 0;
        int leftMax = 0;//不是位置 只是初始化为value=0
        int rightMax = 0;
        while (left < right) {
            if (height[left] < height[right]) { //谁小就以谁那边的Max作为基准 即如果左边的小 那么左指针处盛的最大水量就只与leftMax有关 与left右边的任何一个墙的高度无关,即墙如果低,left指针上最终也会是这个高度,墙如果高 left指针最终也会是这样一个高度
               leftMax = Math.max(height[left], leftMax); //当leftMax有必要更新的时候再更新
                res += leftMax - height[left]; //隐形乘以了1
                left++; //左指针右移一位
            } else {
                rightMax = Math.max(height[right], rightMax);
                res += rightMax - height[right];
                right--;
            }
        }
        return res;
    }
}

but think of another way: this is actually a mono stack related problem, for each value, we need to find the farthest previous decrease sequence until current value and the farthest next increase sequence from current value
the code simple is as folllows, which using only one stack.

class Solution {
    public int trap(int[] height) {
        if (height == null || height.length < 2) return 0;
        
        Stack<Integer> stack = new Stack<>();
        int water = 0, i = 0;
        while (i < height.length) {
            if (stack.isEmpty() || height[i] <= height[stack.peek()]) {
                stack.push(i++);
            } else {
                int pre = stack.pop();
                if (!stack.isEmpty()) {
                    // find the smaller height between the two sides
                    int minHeight = Math.min(height[stack.peek()], height[i]);
                    // calculate the area
                    water += (minHeight - height[pre]) * (i - stack.peek() - 1);
                }
            }
        }
        return water;
    }
}