当前位置: 首页 > news >正文

单调栈: 接雨水

 解法: 雨水面积 = 底边长w*雨水高度h

双指针:

  • 求每个位置的水位高度,以当前位置为中心,双指针分别向左右寻找最高边界。
  • h = min(lHeight, rHeight) - height[i]; w=1

动态规划:

  • 根据已知的边界高度和当前高度比较,确定当前位置的左右边界高度,取最高的左右高度值
  • int[len+2][2]: 存放个位置的左边界高,右边界高;首尾设置虚拟节点表示边界,高度为0
  • 遍历高度:左到右确定左界值。右到左确定右界值
  • h = min(lHeight, rHeight) - height[i]; w=1

单调栈:

  • 栈内元素对应高度值:大到小(栈底到栈头),即栈内可确定左边界(栈内存放下标)
  • 新加元素 符合 单调性:直接加入
  • 新加元素 = 栈头旧元素: 旧元素出栈,新元素入栈 (保证左侧的最右边边界)
  • 新加元素 > 栈头旧元素:右边界确定,栈头出栈,当前栈头为左边界,计算当前凹槽高度的存水量,重复该步骤,直到满足新元素入栈条件
  • 宽(下标间距离)*高(可存高度差):(i-pre-1)*(Math.min(height[i],height[pre])-height[cur])
//双指针法:寻找每个位置上的可堆积的雨水高度,即左右寻找水桶的最高边界,取最低值-底部高度
class Solution {
    public int trap(int[] height) {
        int sum= 0;
        //计算每一个位置可堆积的雨水高度,叠加
         int lheight, rheight;
        for(int i = 0; i < height.length; i++){
            lheight = 0;
            rheight = 0;
            for(int l = i-1; l >= 0; l--){
                lheight = Math.max(lheight,height[l]);
            }
            for(int r = i+1; r < height.length; r++){
                rheight = Math.max(rheight,height[r]);
            }
            int get = Math.min(lheight,rheight)-height[i];
            sum += get>0? get:0;
        }
        return sum;
    }
}


//动态规划:最快,按列计算存水量
class Solution {
    public int trap(int[] height) {
        int len = height.length;
        int[][] dp = new int[len+2][2];//初始值全为0,首尾添加虚拟节点可存水高度一定为0
        int sum= 0;
        for(int left = 1; left <= len; left++){
            dp[left][0] = Math.max(dp[left-1][0],height[left-1]);//左侧高度
            int right = len+2-1-left;
            dp[right][1] = Math.max(dp[right+1][1],height[right-1]);//右侧高度
        }
        for(int i = 1; i <= len; i++){
            int get = Math.min(dp[i][0],dp[i][1])-height[i-1];
            sum += get>0?get:0;
        }
        return sum;
    }
}

//单调栈:按行计算存水量
class Solution {
    public int trap(int[] height) {
        Stack<Integer> index = new Stack<>();
        int sum = 0;
        index.push(0);
        for(int i = 1; i < height.length; i++){
            int cur = index.peek();
            while(!index.isEmpty() && height[i] >= height[cur]){
                cur = index.pop();
                if(!index.isEmpty()){
                    int pre = index.peek();
                    sum += (i-pre-1)*(Math.min(height[i],height[pre])-height[cur]);
                    cur = pre;
                }               
            }
            index.push(i);
        }
        return sum;
    }
}

相关文章:

  • 用C++11 make_shared替代shared_ptr
  • 数据结构之——栈的操作讲解与功能实现
  • 剑指 Offer II 079+080+081+082
  • 前端小tips(持续更新)
  • matlab读取文件
  • php __destruct反序列化原理
  • 通俗易懂,一文学会前端缓存
  • python常用基础笔记
  • centos设置root免密自动登陆
  • JuiceFS 在多云存储架构中的应用 | 深势科技分享
  • 【LeetCode】思维向题笔记总结(持续更新)
  • springboot+vue农产品销售配送网站
  • ISE的FPGA程序加载与固化——Omapl138/TMS320C6748+FPGA核心板
  • SAP ABAP 定义事件以及处理事件
  • 西瓜书-2习题
  • @angular/forms 源码解析之双向绑定
  • conda常用的命令
  • Consul Config 使用Git做版本控制的实现
  • CSS 专业技巧
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • in typeof instanceof ===这些运算符有什么作用
  • interface和setter,getter
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Python学习笔记 字符串拼接
  • SegmentFault 2015 Top Rank
  • socket.io+express实现聊天室的思考(三)
  • spark本地环境的搭建到运行第一个spark程序
  • 精彩代码 vue.js
  • 跨域
  • 来,膜拜下android roadmap,强大的执行力
  • 前端相关框架总和
  • 如何实现 font-size 的响应式
  • 算法系列——算法入门之递归分而治之思想的实现
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • raise 与 raise ... from 的区别
  • 积累各种好的链接
  • #Spring-boot高级
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Note)C++中的继承方式
  • (二)c52学习之旅-简单了解单片机
  • (二开)Flink 修改源码拓展 SQL 语法
  • (十三)Maven插件解析运行机制
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)h264中avc和flv数据的解析
  • (转)jdk与jre的区别
  • (状压dp)uva 10817 Headmaster's Headache
  • *p++,*(p++),*++p,(*p)++区别?
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .NET文档生成工具ADB使用图文教程
  • .NET中GET与SET的用法