• 【CT】LeetCode手撕—42. 接雨水


    题目


    1- 思路

    模式识别:求雨水的面积 ——> 不仅是只求一个比当前元素大的元素,还要求面积

    单调栈

    • 应用场景,需要找到左边比当前元素大的元素

    单调栈实现

    • 当前元素和栈口元素作比较,如果当前元素大于栈口元素,此时收集结果:
    • 例如 栈口元素是 10,如果当前元素是 30
      • 此时找到 元素 10 右侧第一个比 它大的元素值是 30
      • 右侧第一个比他大的元素是 栈里的第二个元素

    单调栈的维护

    • 单调栈与当前元素,存在三种情况,① 等于、②小于、③大于。要用单调栈来存储遍历过的元素
      • 如果小于等于 栈口元素,此时直接入栈
      • 如果大于栈口元素,此时收集结果
        • ①凹槽底部元素: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;

    2- 实现

    ⭐42. 接雨水——题解思路

    在这里插入图片描述

    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;
        }
    }
    

    3- ACM实现

    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));
        }
    }
    
  • 相关阅读:
    python --opencv图像处理形态学(开运算、闭运算、梯度运算、顶帽运算、黑帽运算)
    获取文件md5值
    既生瑜,何生亮?
    【Linux】服务器校准时间
    KMP算法(详解加图解)
    【机器学习】037_暂退法
    【图灵MySQL】深入理解Mysql索引底层数据结构与算法
    IT运维管理平台助力企业打造监、管、控一体化
    【数学知识】—— 质数/约数
    Rust权威指南之枚举和模式匹配
  • 原文地址:https://blog.csdn.net/weixin_44382896/article/details/139888905