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

力扣● 503.下一个更大元素II ● 42. 接雨水

  •  503.下一个更大元素II 

与496.下一个更大元素 I的不同是要循环地搜索元素的下一个更大的数。那么主要是对于遍历结束后,单调栈里面剩下的那些元素。

如果直接把两个数组拼接在一起,然后使用单调栈求下一个最大值就可以。

代码实现的话,不用直接把数组后面再接一个数组,而是单调栈走2遍这个数组即可。

代码如下。第二次遍历使用取余的方法。
 

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {int n=nums.size();vector<int> result(n,-1);stack<int> st;for(int i=0;i<2*n;++i){int k=i%n;while(!st.empty() && nums[k]>nums[st.top()]){result[st.top()]=nums[k];st.pop();}st.push(k);}return result;}
};

  •  42. 接雨水  

依据列来计算更好理解,能引入单调栈:可以看出,因为左侧最高柱子和右侧最高柱子肯定不会存储雨水(左侧和右侧包含自己,因为自己是一侧最高的话不会存储雨水),所以每一列雨水的高度,取决于,该列 左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。

下面图片以柱子4为例,可以看见中间所有柱子都满足这个结论,最两边的柱子不会存储雨水。

转化问题后,有3种办法解决:

  • 会超时的暴力解法。
  • 双指针优化。
  • 重点的单调栈。

1、暴力解法。

对于每个元素,都从左、从右找最大高度的柱子lheight、rheight,所以外层循环是0到n-1,内层循环从i往左,然后从i往右找最大高度的柱子lheight、rheight,最多会查找n次。所以时间复杂度是O(n^2),空间复杂度O(1)。但是会超时。

2、双指针优化。

当前元素的左边、右边最大高度的柱子lheight、rheight其实跟前一个元素的lheight、rheight有关。注意左边最大和右边最大要把自己考虑进去,如果不包含,左边最大/右边最大的可能比自己还小,那么相减是负数,最终结果比正确结果小。

当前i的lheight取决于左边i-1的lheight,rheight取决于右边i+1的rheight。具体如下:

当前i的lheight=max(前一个lheight,height[i]),所以需要从左到右得到lheight。

那么参照lheight,当前i的rheight应该=max(后一个lheight,height[i]),与上面相反,从右到左得到。

根据这个过程先把所有元素的lheight数组和rheight数组求出来,然后再遍历元素的时候,直接就是min(lheight[i],rheight[i])-height[i]。时间复杂度是O(n),空间复杂度O(n)。

代码如下。

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int l1,r1,l2,r2;int count=0;vector<int> lheight(n);vector<int> rheight(n);//初始化lheight[0]=height[0];rheight[n-1]=height[n-1];for(int i=1;i<n-1;++i){//中间元素的lheight和rheightlheight[i]=max(lheight[i-1],height[i]);rheight[i]=max(rheight[i+1],height[i]);}for(int i=n-2;i>0;--i){rheight[i]=max(rheight[i+1],height[i]);}for(int i=0;i<n;++i){if(i==0 || i==n-1)continue;int cur=min(lheight[i],rheight[i])-height[i];count+=cur;}return count;}
};

上面的1、2都是按照列的方式去装水,因为是找左右两边最大元素。

3、单调栈

如果按行装水的话,就可以通过下一个更大元素和上一个最大元素来求。

以上图为例,下标2左边更大是1,右边更大是2,所以自己这行(以下标2柱高0为底,以min(左边更大值,右边更大值)为高,宽度是2个更大值的距离1)可以存储1的雨水;下标4左边更大是2,右边更大是3,所以自己这行(以下标4柱高1为底,以min(左边更大值,右边更大值)=2为高,宽度是2个更大值的距离3)可以存储3的雨水……左边更大和右边更大有1个不存在的则存储雨水为0。

所以要用单调栈计算出上一个更大值和下一个更大值的下标leftmax和rightmax。然后i柱子处可以存储的雨水是:(min(height[leftmax],height[rightmax])-height[i])*(rightmax-leftmax-1)。

怎么计算上一个更大值和下一个更大值呢?还想着2次单调栈,实际上,1次单调栈即可。采用单调递增栈,在元素 i 比栈顶大的情况下,如果栈顶同时也比次栈顶要小,这个时候就出现一个凹槽,也就找到了上一个更大值(次栈顶)和下一个更大值(元素i)。所以这个单调递增栈,必须是严格的单增,这个凹槽一定是次栈顶>栈顶<比栈顶大的元素i。

所以如果元素i==栈顶的话,要么不操作,要么替换这个栈顶,才能满足单调栈。这里需要选择的操作是替换栈顶,因为我们要求宽度的时候 如果遇到相同高度的柱子,需要使用最右边的柱子来计算宽度

如果<栈顶,就直接入栈。

清晰说明了3种情况:

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int count=0;stack<int> st;st.push(0);for(int i=1;i<n;++i){if(height[i]==height[st.top()]){st.pop();st.push(i);}else if(height[i]<height[st.top()])st.push(i);else{while(!st.empty()&&height[i]>height[st.top()]){//有凹槽,top是中间int mid=st.top();st.pop();if(!st.empty()){//取栈顶,都要判断非空int h=min(height[i],height[st.top()])-height[mid];//高int w=i-st.top()-1;//宽count+=w*h;}}st.push(i);}}return count;}
};

相等的情况pop()之前应该检查是否为空,但是初始和每一次循环结尾都有入栈操作,所以这里不用加。

简化。简化后的3个pop()操作都有可能遇栈空,所以都要加条件,否则报错:

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int count=0;stack<int> st;st.push(0);for(int i=1;i<n;++i){while(!st.empty()&&height[i]>height[st.top()]){//有凹槽,top是中间int mid=st.top();st.pop();if(!st.empty()){//取栈顶,都要判断非空int h=min(height[i],height[st.top()])-height[mid];//高int w=i-st.top()-1;//宽count+=w*h;}}if(!st.empty()&&height[i]==height[st.top()]){st.pop();}st.push(i);}return count;}
};

相关文章:

力扣● 503.下一个更大元素II ● 42. 接雨水

503.下一个更大元素II 与496.下一个更大元素 I的不同是要循环地搜索元素的下一个更大的数。那么主要是对于遍历结束后&#xff0c;单调栈里面剩下的那些元素。 如果直接把两个数组拼接在一起&#xff0c;然后使用单调栈求下一个最大值就可以。 代码实现的话&#xff0c;不用直…...

Java中的包装类

Java中的包装类 一、包装类是什么&#xff1f;二、对应关系&#xff1a;三、举例说明&#xff1a;Integer构造器&#xff1a;包装类特有的机制&#xff1a;自动装箱 自动拆箱常用方法 总结 一、包装类是什么&#xff1f; 以前定义变量&#xff0c;经常使用基本数据类型&#x…...

实时数仓的另一种构建方法starRocks的物化视图

一、 StarRocks是什么 StarRocks是一个分布式的、高性能的OLAP(联机分析处理)数据库,物化视图在StarRocks中具有重要作用。 二、 StarRocks物化视图能干啥 物化视图(Materialized Views)是数据库中的预先计算结果的存储。它们是由一个或多个基础表的聚合数据组成的,这…...

【PHP】通过PHP实时监控Apache、MySQL服务运行状态

一、前言 有些时候我们需要监控一些服务的运行状态&#xff0c;比如说Apach或MySQL的运行状态&#xff0c;最近工作中也开发了这方面的功能&#xff0c;记录下来怎样使用PHP语言来实时监控Apache、MySQL服务的运行状态。 如果想一键开启Apache或MySQL等其他服务可以看这篇文章…...

ETL的全量和增量模式

在当今信息爆炸的时代&#xff0c;数据管理已经成为各行各业必不可少的一环。而在数据管理中&#xff0c;全量与增量模式作为两种主要的策略&#xff0c;各自具有独特的优势和适用场景&#xff0c;巧妙地灵活运用二者不仅能提升数据处理效率&#xff0c;更能保障数据的准确性。…...

常用的IDE推荐

程序员在选择集成开发环境&#xff08;IDE&#xff09;时&#xff0c;会考虑多种因素&#xff0c;包括易用性、功能丰富性、性能以及是否支持他们正在使用的编程语言。以下是一些建议的IDE及其优点&#xff1a; 1.JetBrains PyCharm&#xff1a;专为Python开发而设计的IDE。 优…...

6、kubenetes 卷

1、什么是卷 在某些场景下&#xff0c;我们可能希望新的容器可以在之前容器结束的位 置继续运⾏&#xff0c;⽐如在物理机上重启进程。可能不需要&#xff08;或者不想要&#xff09; 整个⽂件系统被持久化&#xff0c;但又希望能保存实际数据的⽬录。 Kubernetes通过定义存储…...

前端学习笔记 | Node.js

一、Node.js入门 1、什么是Node.js 定义&#xff1a;是跨平台JS运行环境&#xff08;可以独立执行JS的环境&#xff09;作用&#xff1a; 编写数据接口&#xff0c;提供网页资源功能等等前端工程化&#xff1a;为后续学Vue和React等框架做铺垫 2、Node.js为何能执行JS&#xff…...

Spark-Scala语言实战(3)

在之前的文章中&#xff0c;我们学习了如何在来如何在IDEA离线和在线安装Scala&#xff0c;想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实…...

diffusion model(十四): prompt-to-prompt 深度剖析

infopaperPrompt-to-Prompt Image Editing with Cross Attention Controlgithubhttps://github.com/google/prompt-to-promptOrg:Google Research个人复现https://github.com/myhz0606/diffusion_learning个人博客主页http://myhz0606.com/article/p2p 1 前言 基于扩散模型&a…...

线性表的顺序表示(顺序表)

静态分配&#xff1a; #include <stdbool.h> #include <stdio.h>typedef int ElementType;#define MaxSize 50 typedef struct {ElementType data[MaxSize];int length; }SqList;//初始化 //SqList L; void InitList(SqList L) {L.length 0; }//插入 bool ListIn…...

矩阵A的LU分解

文章目录 1. 矩阵的逆矩阵1.1 AB的逆矩阵1.2 转置矩阵 2. 2X2矩阵A消元3. 3X3矩阵A消元4. 运算量5. 置换矩阵-左行右列 本文主要目的是为了通过矩阵乘法实现矩阵A的分解。 1. 矩阵的逆矩阵 1.1 AB的逆矩阵 假设A,B矩阵都可逆 A ( B B − 1 ) A − 1 I (1) A(BB^{-1})A^{-1}…...

深入了解Flutter中Future的全部工厂方法及使用

在Flutter中&#xff0c;Future是一种表示异步操作结果的对象。它代表了一个可能已经完成或尚未完成的计算&#xff0c;可以用来处理异步任务。Flutter提供了多种工厂方法来创建Future对象&#xff0c;每种方法都有其特定的用途和优势。在本文中&#xff0c;我们将深入探讨Flut…...

python的BBS论坛系统flask-django-nodejs-php

为了更好地发挥本系统的技术优势&#xff0c;根据BBS论坛系统的需求&#xff0c;本文尝试以B/S架构设计模式中的django/flask框架&#xff0c;python语言为基础&#xff0c;通过必要的编码处理、BBS论坛系统整体框架、功能服务多样化和有效性的高级经验和技术实现方法&#xff…...

vulnhub-----pWnOS1.0靶机

文章目录 1.信息收集2.漏洞测试3.爆破hash4.提权 首先拿到一台靶机&#xff0c;就需要知道靶机的各种信息&#xff08;IP地址&#xff0c;开放端口&#xff0c;有哪些目录&#xff0c;什么框架&#xff0c;cms是什么&#xff0c;网页有什么常见的漏洞&#xff0c;如sql注入&…...

vue 消息左右滚动(前后无缝衔接)

演示效果 封装的组件 <!--* Author:* Date: 2024-03-21 19:21:58* LastEditTime: 2024-03-21 20:31:50* LastEditors: Please set LastEditors* Description: 消息左右滚动 --> <template><divid"textScroll"class"text-scroll"mousemove&…...

Qt如何直接处理系统事件(比如鼠标事件),而不是post事件

#include <QtGui/5.15.2/QtGui/qpa/qwindowsysteminterface.h> // 方便调试事件 QWindowSystemInterface::setSynchronousWindowSystemEvents(true); 直接再 qWindowsWndProc函数中处理 通常情况: 事件被放到一个队列中...

Web前端笔记+表单练习+五彩导航

一、笔记 表单&#xff1a;数据交互的一种方式 登录、注册、搜索 <from> <input type""> --- <input type"text"> --- 普通输入框&#xff0c;内容在一行显示 <input type"password"> --- 密码框 <input type"…...

软件架构和基于架构的软件开发方法知识总结

一、软件架构定义 软件架构为软件系统提供了一个结构、行为和属性的高级抽象 软件架构是一种表达&#xff0c;使软件工程师能够&#xff1a; &#xff08;1&#xff09;分析设计在满足所规定的需求方面的有效性 &#xff08;2&#xff09;在设计变更相对容易的阶段&#xff0c;…...

环信新版单群聊UIKit集成指南——Android篇

前言 环信新版UIKit已重磅发布&#xff01;目前包含单群聊UIKit、聊天室ChatroomUIKit&#xff0c;本文详细讲解Android端单群聊UIKit的集成教程。 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界…...

如何用强化学习让AI学生‘挑老师’?动态权重知识蒸馏实战指南

强化学习驱动的动态权重知识蒸馏&#xff1a;让AI学生自主选择最优教师 在自然语言处理领域&#xff0c;知识蒸馏已经成为模型压缩和知识迁移的重要技术。传统多教师知识蒸馏方法通常采用固定权重分配策略&#xff0c;忽视了学生模型在不同训练阶段和不同样本上的学习能力差异。…...

【仅限首批200家认证企业获取】Java 25虚拟线程生产就绪检查清单(含JDK25.0.1 Hotfix补丁验证报告)

第一章&#xff1a;Java 25虚拟线程生产就绪核心定义与认证准入机制Java 25正式将虚拟线程&#xff08;Virtual Threads&#xff09;从预览特性升级为**生产就绪&#xff08;Production-Ready&#xff09;** 的标准特性&#xff0c;其核心定义聚焦于轻量级、高密度、可扩展的并…...

三步解锁纯净文档:告别百度文库的付费与广告困扰

三步解锁纯净文档&#xff1a;告别百度文库的付费与广告困扰 【免费下载链接】baidu-wenku fetch the document for free 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wenku 你是否曾在百度文库上找到了完美的参考资料&#xff0c;却被付费提示、广告弹窗和复杂…...

Java AES/ECB/PKCS5Padding加解密实战:从JCE配置到Base64/Hex输出

Java AES/ECB/PKCS5Padding加解密实战&#xff1a;从JCE配置到Base64/Hex输出 在数据安全日益重要的今天&#xff0c;加密技术已成为开发者必备的技能之一。AES&#xff08;Advanced Encryption Standard&#xff09;作为目前最常用的对称加密算法&#xff0c;因其安全性和高效…...

如何从零开始组装高性能Voron 2.4 CoreXY 3D打印机:新手完整指南

如何从零开始组装高性能Voron 2.4 CoreXY 3D打印机&#xff1a;新手完整指南 【免费下载链接】Voron-2 Voron 2 CoreXY 3D Printer design 项目地址: https://gitcode.com/gh_mirrors/vo/Voron-2 还在为商业3D打印机的高昂价格和有限性能而烦恼吗&#xff1f;今天我要为…...

FISCO BCOS 多方协作治理组件

组件定位 区块链历经10余年的发展,基础技术框架逐渐完善,链上承载的业务越来越丰富,参与方越来越多。多方协作能否顺畅进行、业务摩擦能否得到有效解决、既往治理策略和实践能否满足日后高速发展的需求……行业关注的重点逐步聚焦到这些更具挑战性的难题上。 2021年1月,微…...

AI时代新型的项目管理应该是什么样的?侣

AI训练存储选型的演进路线 第一阶段&#xff1a;单机直连时代 早期的深度学习数据集较小&#xff0c;模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低&#xff0c;吞吐量极高&#xff0c;也就是“数据离…...

2026届必备的五大AI论文工具横评

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 技术人工智能的发展速度飞快&#xff0c;论文AI类网站成了可辅助学术写作领域的重要工具&…...

【HTML动态交互实战】模拟股市波动可视化系统

1. 从零搭建股市波动可视化系统 最近在做一个金融数据分析的小项目&#xff0c;需要模拟股票价格波动并可视化展示。作为一个前端开发者&#xff0c;我第一时间想到用HTML5 Canvas来实现这个需求。下面就把我的实现思路和踩过的坑分享给大家。 先说说为什么要用Canvas而不是S…...

R语言实战:RStudio高效编程快捷键全解析

1. 为什么你需要掌握RStudio快捷键&#xff1f; 作为一个用了十年R语言的老兵&#xff0c;我见过太多新手在RStudio里重复点击菜单栏的惨状。想象一下&#xff1a;当你处理一份百万行的数据集时&#xff0c;每次运行代码都要用鼠标去点那个小小的"Run"按钮&#xff0…...