单调栈的使用一:接雨水

news2025/2/2 12:50:08

文章目录

      • 1、单调栈接雨水的过程
      • 2、算法正确性的关键点:
      • 3、简化理解:
      • 4、算法的实现

题目路径: 42.接雨水
其他解法: 接雨水(动态规划/双指针/贪心)
单调栈原理: 单调栈和单调队列
在这里插入图片描述

  单调栈直接用于找每个元素"左右侧"第一个更高的元素,并不直接给出左右两侧最高的元素。不过,在接雨水问题中,单调栈的应用逻辑稍有不同,它的核心在于利用栈来识别和计算每个凹形区间(即可以积水的区间)。一旦识别出来就计算其能积水的量,然后进行填充。填充后,你可以认为柱形变高了。
在这里插入图片描述

1、单调栈接雨水的过程

在这里插入图片描述栈中永远是递减序列,一旦遇到凹型区域就砌平。

  当我们在遍历数组时,遇到一个当前遍历的柱子高度比栈顶元素的高度大的情况,这意味着我们找到了一个潜在的凹形区域的右边界。这个凹形区域的左边界是栈中的次栈顶元素。此时,栈顶元素是凹形区域的底部,而当前柱子成为了凹形区域的右边界。
  凹形区域的宽度是(j - i - 1),其中i是次栈顶元素的位置,j是当前柱子的位置。凹形区域可以填充的水的高度是由ij位置的柱子的较矮者决定的,减去凹底的高度,即min(height[i], height[j]) - height[mid],这里mid是凹底,即栈顶元素的位置。因此,这个凹形区域可以积累的水量是(min(height[i], height[j]) - height[mid]) * (j - i - 1)
  这个计算过程会一直重复进行,直到栈为空或者当前遍历的柱子的高度不再大于栈顶元素的高度。通过这种方式,我们可以确保计算出数组中所有可能的凹形区域中积累的水。
  实际上,这个计算过程不是简单地填充每个凹形区域之间的每一列水,而是根据凹形区域的左右边界高度和凹底高度计算出该区域能够积累的水量。这种方法在一旦有凹型区域时就把该凹型区域填充起来,使得每次虽然看起来像是只填充一列但实际上是每次都把柱子砌平,使得每次填充实际上是在整个中间是平坦水柱构成凹型区域上进行填充
在这里插入图片描述中间是遍历过程中被砌平的。

  因此,单调递减栈在这个问题中的应用确保了每次计算的是有效的凹形区域,并且能够正确地计算出每个区域能够积累的水量,从而得到整个数组中能够积累的总水量。这种方法的有效性和效率使得它成为解决接雨水问题的强大工具。

2、算法正确性的关键点:

  1. 局部积水量的计算:单调栈用于确定每个凹形区间,并计算这个区间内的积水量。对于栈中每个元素,它的左侧边界是栈中之前的元素,右侧边界是当前考察的元素。这个“左边界-凹底-右边界”构成了一个可以积水的凹形区间。

  2. 凹形区间的最高边界:虽然单调栈直接找到的是左右侧第一个更高的元素,但是解决接雨水问题可以认为每次找到一个凹型区间,则将该区间填充,虽然本次可能不能考虑到整个的最高边界,但是其他水柱的计算方法仍然会使其填充到最高

  3. 迭代构建:通过迭代的方式,栈帮助我们一步步向右“扫描”数组,每次遇到能形成新的凹形区间的元素时,就计算该区间的积水量。这种方式确保了即便是在多个嵌套的凹形区间中,每个区间的积水量也能被准确计算。

3、简化理解:

  • 当我们遍历到新的高度时,如果这个高度小于栈顶元素对应的高度,它就被推入栈中,意味着可能会有一个新的凹形区间开始形成。
  • 如果这个高度大于栈顶元素对应的高度,那么栈顶元素(凹底)和栈中之前的元素(左边界)、当前元素(右边界)一起形成一个凹形区间。我们可以立即计算出这个区间内的积水量,然后移除栈顶元素。
  • 这个过程重复进行,直到当前元素小于新的栈顶元素(意味着不能形成新的凹形区间)或栈为空(意味着左边没有更高的边界了)。

4、算法的实现

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        stack<int> stk;
        int n = height.size();
        for (int i = 0; i < n; ++i) {
            while (!stk.empty() && height[i] > height[stk.top()]) {
                int top = stk.top();
                stk.pop();
                if (stk.empty()) {
                    break;
                }
                int left = stk.top();
                int currWidth = i - left - 1;
                int currHeight = min(height[left], height[i]) - height[top];
                ans += currWidth * currHeight;
            }
            stk.push(i);
        }
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1555258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Topaz Video AI for mac 视频增强软件

Topaz Video AI for Mac是一款专为Mac用户设计的视频增强软件&#xff0c;它利用先进的人工智能技术和机器学习算法&#xff0c;为用户提供卓越的视频编辑和增强体验。 软件下载&#xff1a;Topaz Video AI for mac v4.2.2激活版 这款软件能够快速提高视频的清晰度、色彩饱和度…

Python Flask Web框架初步入门

前言 flask基础 搭建flask服务器 定义html 使用templates模板定义页面的html html页面编写 render_template传参变量 定义图片 创建static目录&#xff0c;存入图片 html编写 flask入门 网站多域名 网站之间超链接跳转 入门案例 将centos的rpm包下载链接集成到自…

Linux(CentOS7.5) 安装部署 Python3.6(超详细!包含 Yum 源配置!)

文章目录 1.配置 Yum 源2.下载 Python3 包3. 解压4.安装依赖环境5.安装出错场景 6.创建软链接7.配置 Python3 的环境变量8.验证补充&#xff1a;安装 openssl-devel补充&#xff1a;pip3 源配置 1.配置 Yum 源 # 注意&#xff01;&#xff01;&#xff01;请先切换到 root 账号…

什么是搜索引擎(SEO)爬虫它们是如何工作的?

什么是搜索引擎&#xff08;SEO&#xff09;爬虫&它们是如何工作的&#xff1f; 你的网站上有蜘蛛&#x1f577;️。别抓狂&#xff01;我说的不是真正的八条腿的蜘蛛&#x1f577;️。 我指的是搜索引擎优化爬虫。他们是实现SEO的机器人。每个主要的搜索引擎都使用爬虫来…

存储阵列从哪些方面改善影视后期制作环境

在4K/8K视频越来越成为影视制作主流的今天&#xff0c;超大的影视文件给项目按时完成带来了严重的挑战。对于影视工作室来说要想赶上进度&#xff0c;在存储的选择上通常有三个难题亟待解决&#xff1a;怎么搭建高性能影视协作环境? 文件量增长怎么扩展现有的存储? 如何有效的…

NumPy介绍及其应用领域

1.NumPy介绍 ​NumPy&#xff08;Numerical Python&#xff09;是 Python 的一个开源的扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库。NumPy的前身为Numeric&#xff0c;起初由Jim Hugunin与其他协作者共同开发&…

Elment ui 动态表格与表单校验 列表数据 组件

组件做个记录&#xff0c;方便以后会用到。 效果&#xff1a; 代码 &#xff1a; <template><el-dialog title"商品详情" :visible.sync"dialogVisible" width"80%"><el-tabs v-model"activeTab"><el-tab-pane…

数据可视化Grafana Windows 安装使用教程(中文版)

1.跳转连接 天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/site?url 2.下载应用程序 官网地址&#xff1a;Grafana get started | Cloud, Self-managed, Enterprisehttps://grafana.com/get/ 3.修改配置文件 grafana\conf\defaults 4.启动\bin\目录下serve应用程序 浏…

C#属性显示

功能&#xff1a; 显示对象的属性&#xff0c;包括可显示属性、可编辑属性、及不可编辑属性。 1、MainWindow.xaml <Window x:Class"FlowChart.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sche…

使用filezilla连接Ubuntu22.04虚拟机

获取电脑IP和虚拟机IP ① 在windows下ctrlR再输入cmd&#xff0c;打开指令窗口&#xff0c;输入 ipconfig 虚拟机连接电脑用的是NAT模式&#xff0c;故看VMnet8的IP地址 ② 查看虚拟机IP地址 终端输入 ifconfig 如果没安装&#xff0c;按提示安装net-tools sudo apt install …

vue3封装Element导航菜单

1. 导航外层布局 AsideView.vue <template><el-menu:default-active"defaultActive"class"my-menu":collapse"isCollapse":collapse-transition"false"open"handleOpen"close"handleClose"><menu…

云渲染实用工具:3ds max怎么改低版本?

3ds Max是建模领域广泛采用的专业软件&#xff0c;它通过定期更新来不断增强功能和提升性能。但这些频繁的更新有时会导致一些插件暂时无法与新版本完全兼容。为了解决这个问题&#xff0c;设计师们可以采用一个简单有效的方法&#xff0c;那就是将较新版本的3ds Max文件进行版…

拆分巨石:将MVPS和MVAS应用于遗留应用程序——可持续架构(六)

前言 MVP 和 MVA 的概念不仅适用于新应用程序&#xff1b;它们提供了一种新颖的方式来审视对遗留系统的范围变更&#xff0c;以防止过快地承担过多的变化 - 参见图1。MVA 可以帮助组织评估和更新其技术标准&#xff0c;通过展示新技术如何真正对支持 MVP 至关重要。创建 MVA 可…

uniapp对接极光推送(国内版以及海外版)

勾选push&#xff0c;但不要勾选unipush 国内版 网址&#xff1a;极光推送-快速集成消息推送功能,提升APP运营效率 (jiguang.cn) 进入后台&#xff0c;并选择对应应用开始配置 配置安卓包名 以及ios推送证书&#xff0c;是否将生产证书用于开发环境选择是 ios推送证书…

HarmonyOS ArkTS 骨架屏加载显示(二十五)

目录 前言1、骨架屏代码显示2、代码中引用3、效果图展示 前言 所谓骨架屏&#xff0c;就是在页面进行耗时加载时&#xff0c;先展示的等待 UI, 以告知用户程序目前正在运行&#xff0c;稍等即可。 等待的UI大部分是 loading 转圈的弹窗&#xff0c;有的是自己风格的小动画。其实…

【ERP原理与应用】作业·思考题三、四

思考题三 P77第四章3&#xff0c; 6&#xff0c;8 3.生产规划的基本内容是什么&#xff1f; 生产规划是根据企业未来一段时间内预计资源可用量和市场需求量之间的平衡所制定的概括性设想是根据企业所拥有的生产能力和需求预测&#xff0c;对企业未来较长一段时间内的产品、产…

elasticsearch _cat/indices docs.count is different than <index>/_count

今天遇到一个问题&#xff0c;kibana中看到文档数与下面语句查询到的不同 GET /_cat/count/jiankunking_xxxxx_product_expand_test?v GET /jiankunking_xxxxx_product_expand_test/_search?track_total_hitstrue语句查询结果 epoch timestamp count 1711433785 06:16…

用navicat进行mysql表结构同步

用navicat进行mysql表结构同步 前言新增一个列然后进行表结构同步删除一个列然后进行表结构同步把Int列转成TinyInt列&#xff0c;看数字溢出的情况下能不能表结构同步总结 前言 从同事那边了解到还能用navicat进行表结构同步&#xff0c;他会在发布更新的时候&#xff0c;直接…

MPDataDoc类介绍

MPDataDoc类介绍 使用mp数据库新接口mp_api.client.MPRester获取数据&#xff0c;例子如下&#xff1a; from mp_api.client import MPResterwith MPRester(API_KEY) as mpr:docs mpr.summary.search(material_ids["mp-1176451", "mp-561113"])以上代码返…

vue3+threejs新手从零开发卡牌游戏(二十一):添加战斗与生命值关联逻辑

首先将双方玩家的HP存入store中&#xff0c;stores/common.ts代码如下&#xff1a; import { ref, computed } from vue import { defineStore } from piniaexport const useCommonStore defineStore(common, () > {const _font ref() // 字体const p1HP ref(4000) // 己…