接雨水

单调栈做法

42. 接雨水

public class mylist {
    public static int trap(int[] height) {
        int lens = height.length;

        // 形成凹槽至少需要三个圆柱,少于三个无法实现
        if(lens<=2) return 0;

        // 存储的是height[]数组的下标
        Deque<Integer> queue = new LinkedList<>();
        // 先加入第一个元素
        queue.add(0);
        // 记录的是总的接雨水数量
        int sum = 0;

        for(int i = 1; i <lens; i++){
            if(height[i]<height[queue.getLast()]){
                queue.add(i);                           // case 1  当当前遍历元素小于队列尾部(栈顶部)元素时,加入栈
            }
            else if(height[i]==height[queue.getLast()]){// case 2 ,当当前元素等于队尾元素时
                queue.pollLast();                       // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。不加会计算左侧和中级相等的情况会加个0
                queue.add(i);
            }
            else{  //case 3  此时当前元素大于队尾元素,有雨水可存
                while(!queue.isEmpty()&&height[i]>height[queue.getLast()]){ //当当前元素大于队尾元素,并且队列不为空
                    // 队尾的元素 是 mid,也是队列尾部元素,并弹出
                    int mid = queue.pollLast();
                    if(!queue.isEmpty()){
                        // 弹出后,此时尾部元素时左侧元素
                        int left = queue.getLast();
                        // 计算存水高度
                        int h = Math.min(height[left],height[i])-height[mid];
                        // 计算水底部
                        int w = i-left-1;
                        sum+=h*w;
                    }
                }
                queue.add(i);
            }
        }
        return sum;
    }


    public static void main(String[] args) {
        int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
        int trap = trap(height);
        System.out.println(trap);
    }
}
posted @ 2023-04-20 10:21  Chenyi_li  阅读(25)  评论(0)    收藏  举报