D51+D52|接雨水

503.下一个更大元素ll

初始思路:这样这道题就变成了一道很纯粹的单调栈问题,因为只涉及了一个数组。但又因为这个数组是一个循环数组所以问题又变的有些复杂。

初始思路:

在循环数组的问题中,比较需要考虑的就是数组中最后一个数字出现在数组头部的问题,所以考虑将创建一个新数组,数组中的元素为原数组元素+数组中最后一个数组前的元素,然后使用基本单调栈的方法处理该问题。answer数组和原数组大小相同。

class Solution {public int[] nextGreaterElements(int[] nums) {int[] ans = new int[nums.length];Arrays.fill(ans,-1);int[] newnums = new int[2*nums.length-1];for(int i = 0;i<newnums.length;i++){if(i<nums.length){newnums[i] = nums[i];}else{newnums[i] = nums[i-nums.length];}}Stack<Integer> st = new Stack<>();st.push(0);for(int i = 1;i<newnums.length;i++){if(newnums[i]<=newnums[st.peek()]){st.push(i);}else{while(!st.isEmpty()&&newnums[i]>newnums[st.peek()]){int pos = st.peek()<nums.length?st.peek():st.peek()-nums.length;ans[pos] = newnums[i];st.pop();}st.push(i);}}return ans;}
}

题解复盘:

直接使用取余操作代替填充数组!!

class Solution {public int[] nextGreaterElements(int[] nums) {//边界判断if(nums == null || nums.length <= 1) {return new int[]{-1};}int size = nums.length;int[] result = new int[size];//存放结果Arrays.fill(result,-1);//默认全部初始化为-1Stack<Integer> st= new Stack<>();//栈中存放的是nums中的元素下标for(int i = 0; i < 2*size; i++) {while(!st.empty() && nums[i % size] > nums[st.peek()]) {result[st.peek()] = nums[i % size];//更新resultst.pop();//弹出栈顶}st.push(i % size);}return result;}
}

42.接雨水 

初始思路&&题解复盘:

大概能理解雨水的数量是如何计算出来的,但是找到一套通用的计算公式还是比较困难的。

单调栈是按照行方向来计算雨水的。

以下逻辑主要就是三种情况

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
  • 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
  • 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]

先将下标0的柱子加入到栈中,st.push(0);。 栈中存放我们遍历过的元素,所以先将下标0加进来。

然后开始从下标1开始遍历所有的柱子,for (int i = 1; i < height.size(); i++)

如果当前遍历的元素(柱子)高度小于等于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。

如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了,如图所示:

42.接雨水4

取栈顶元素,将栈顶元素弹出,这个就是凹槽的底部,也就是中间位置,下标记为mid,对应的高度为height[mid](就是图中的高度1)。

此时的栈顶元素st.top(),就是凹槽的左边位置,下标为st.top(),对应的高度为height[st.top()](就是图中的高度2)。

当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](就是图中的高度3)。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!

那么雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度,代码为:int h = min(height[st.top()], height[i]) - height[mid];

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度),代码为:int w = i - st.top() - 1 ;

当前凹槽雨水的体积就是:h * w

class Solution {public int trap(int[] height) {Stack<Integer> st = new Stack<>();st.push(0);int res = 0;int mid = 0;int h = 0;int weight = 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()]){mid = height[st.pop()];if(!st.isEmpty()){h = Math.min(height[i],height[st.peek()])-mid; weight = i-st.peek()-1;res = res +h*weight;}}st.push(i);}}return res;}
}

84.柱状图中最大的矩形

同上:如何在单调栈的规律中找到求最大矩形的计算规律是一个有点想不明白的问题。

初始思路&&题解复盘:

只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。

所以本题单调栈的顺序正好与接雨水反过来。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度(理解如何由单调栈问题思考出计算最大面积的方式)

                        int w = right - left - 1;int h = heights[mid];result = max(result, w * h);

理解为什么在首尾均需要添加0元素。

如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了。 如图:

那么结尾加一个0,就会让栈里的所有元素,走到情况三的逻辑。

开头为什么要加元素0?

如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。

(mid、left,right 都是对应版本一里的逻辑)

因为 将 8 弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。

之后又将6 加入栈(此时8已经弹出了),然后 就是 4 与 栈口元素 8 进行比较,周而复始,那么计算的最后结果resutl就是0。 如图所示:

所以我们需要在 height数组前后各加一个元素0。

添加0元素部分代码:

        int[] newHeight = new int[heights.length + 2];System.arraycopy(heights, 0, newHeight, 1, heights.length);newHeight[heights.length+1] = 0;newHeight[0] = 0;

System.arraycopy(int[] arr, int star,int[] arr2, int start2, length);

5个参数,
第一个参数是要被复制的数组
第二个参数是被复制的数字开始复制的下标
第三个参数是目标数组,也就是要把数据放进来的数组
第四个参数是从目标数据第几个下标开始放入数据
第五个参数表示从被复制的数组中拿几个数值放到目标数组中
 

class Solution {public int largestRectangleArea(int[] heights) {int[] newheights = new int[heights.length+2];System.arraycopy(heights,0,newheights,1,heights.length);newheights[0]  = 0;newheights[newheights.length-1] = 0;Stack<Integer> st = new Stack<>();st.push(0);int res = 0;for(int i = 1;i<newheights.length;i++){if(newheights[i]>=newheights[st.peek()]){st.push(i);}else{while(!st.isEmpty()&&newheights[i]<newheights[st.peek()]){int mid = st.pop();int height = newheights[mid];int weight = i-st.peek()-1;res = Math.max(res,height*weight);}st.push(i);}}return res;}
}

单调栈总结 

单调栈问题入门,找一个元素右边第一个比该元素大的值时考虑使用单调栈,从栈顶到栈底如果是递增趋势(加入的元素是比peek()小的)。找右边第一个元素比该元素值大时为相反情况。需要注意的是,此处我们需要在栈中存放的数值是数组下标。

与上一题相同,一些区别是因为无需考虑数组下标,栈中可以直接存放元素,因为数组之中没有重复元素,所以可以在数组2中寻找完然后再用map对应到数组1中。

这个系列中最简单的一道,循环的部份用取余处理。 


接雨水,横向求取面积,找到左边比当前大的值,右边比当前大的值,height = Math.min(左、右)-mid,weight = 右下标-左下标-1;

 

 柱状图中最大的矩形,找到左边比当前小的值和右边比当前小的值,height = mid ,weight就是右下标-左下标-1;

后两道题的难点计算面积并且更新。

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

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

相关文章

web——德州扑克

1.此案例只用于学习 2.未接入游戏规则 HTML代码部分 <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width"><meta name"Poker Skin" content&quo…

模式识别实验三

实验三 一  实验名称 感知器设计 二 目的和意义 使用感知器完成线性分类任务 三 操作步骤或算法结构 数据预处理。载入数据文件&#xff08; iris.csv 文件&#xff09;中的数据&#xff0c;并将其分成样本向量矩阵X和样本分类结果向量 G \bf G G。 给 4 4 4 列向量的…

【Vue3】2-5 : 指令系统与事件方法及传参处理

本书目录&#xff1a;点击进入 一、标签属性中的使用 - 指令系统 1.1 那么模板语法是否可以在标签属性中进行使用呢? ▶ 当然可以&#xff1a;使用 指令系统 二、指令系统 2.1 v-bind 2.2 v-on 三、实战 3.1 methods 选项 3.2 $event语法 一、标签属性中的使用 - 指令…

RT_Thread 调试笔记:时间相关,时钟管理函数,延时,定时器、 毫秒转换为时分秒 等

说明&#xff1a;记录日常使用 RT_Thread 开发时做的笔记。 持续更新中&#xff0c;欢迎收藏。 1. 延时函数 1. us延时函数 rt_hw_us_delay(rt_uint32_t us);//输如数据是us rt_hw_us_delay(200);//输入数据是us 2. ms延时函数 rt_thread_mdelay(1000);//输入数据是ms 2…

【教学类-综合练习-07】20240102 大4班 综合材料 (涂色类)对称动物面具,对称蝴蝶、头饰等

背景需求 年终了&#xff0c;清理库存&#xff0c;各种打印的题型纸都拿出来&#xff0c;当个别化学习材料 教学过程&#xff1a; 时间&#xff1a;2024年1月2日 班级&#xff1a;大4班 人数&#xff1a;25人 这次混了一点“EBRU湿拓郁金香”的纸片&#xff0c; 裁剪花朵…

从零学Java - String类

Java String类 文章目录 Java String类1 String1.1 常用两种创建方式1.2 比较两种创建方式1.3 字符串不可变性1.4 面试题 2 常用方法2.1 练习 3 可变字符串3.1 常用方法3.2 验证StringBuilder的高效性3.3 练习3.4 面试题: 4 正则表达式4.1 元字符4.2 其他字符4.2.1 预定义字符4…

基于Tosca和Terraform的多云资源编排探索

01 导言 随着企业采用多云战略和迁移到云平台&#xff0c;需要依赖不同的云资源来支持业务系统。传统的手动开通和配置资源关联关系的方法在多云环境下变得耗时且复杂&#xff0c;给运维带来困难。 为了应对多云环境中基础设施管理的复杂性&#xff0c;寻找一种高效的多云资源编…

mysql索引失效的情况

目录 1破坏最左前缀法则2在索引列上做任何计算、函数操作&#xff0c;会导致索引失效而转向全表扫描。3存储引擎不能使用索引中范围条件右边的列4Mysql在使用不等于时无法使用索引会导致全表查询5is null可以使用索引&#xff0c;但是is not null无法使用索引6like以通配符开头…

Packet Tracer - Configure AAA Authentication on Cisco Routers

Packet Tracer - 在思科路由器上配置 AAA 认证 地址表 目标 在R1上配置本地用户账户&#xff0c;并使用本地AAA进行控制台和vty线路的身份验证。从R1控制台和PC-A客户端验证本地AAA身份验证功能。配置基于服务器的AAA身份验证&#xff0c;采用TACACS协议。从PC-B客户端验证基…

软件测试|测试平台开发-Flask入门:Flask动态路由

前言 之前我们介绍了flask发送http请求&#xff0c;以及flaskURL的详解&#xff0c;我们使用的路由都是固定的&#xff0c;一个路径和一个视图函数绑定&#xff0c;当访问这条路径时会触发相应的处理函数。但是当我们要处理更为复杂的情况时&#xff0c;比如我们有多个用户&am…

Mybatis面经

Mybatis &#x1f4d1;前言 本文主要是【Mybatis】——Mybatis面经的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每…

【书生·浦语大模型实战营03】《基于 InternLM 和 LangChain 搭建你的知识库》学习笔记

《基于 InternLM 和 LangChain 搭建你的知识库》 常见术语 RAG: Retrieval Augmented Generation&#xff0c;检索增强生成 1. 大模型开发范式 1.1 RAG VS Finetune RAGFinetune低成本可个性化微调可实时更新知识覆盖面广受基座模型影响大成本高昂单次回答知识有限无法实时…

Elasticsearch:Search tutorial - 使用 Python 进行搜索 (二)

这个是继上一篇文章 “Elasticsearch&#xff1a;Serarch tutorial - 使用 Python 进行搜索 &#xff08;一&#xff09;” 的续篇。在今天的文章中&#xff0c;我们接着来完成如何进行分页及过滤。 分页 - pagination 应用程序处理大量结果通常是不切实际的。 因此&#xff0…

代码随想录二刷 |二叉树 | 验证二叉搜索树

代码随想录二刷 &#xff5c;二叉树 &#xff5c; 验证二叉搜索树 题目描述解题思路递归法迭代法 代码实现递归法迭代法 题目描述 98.验证二叉搜索树 给定一个二叉树&#xff0c;判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征&#xff1a; 节点的左子…

Eureka的自我保护机制

一&#xff1a;Eureka的自我保护机制是什么&#xff1f; 保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式&#xff0c;Eureka Server将会尝试保护其服务注册表中的信息&#xff0c;不再删除服务注册表中的数据&#xff0c;也就是不…

关于电脑屏幕亮度的调整,看这篇文章就够了

你可能需要定期更改屏幕亮度。当外面很亮的时候,你想把它调大,这样你就能看到。当你在黑暗的房间里时,你会希望它变暗,这样就不会伤害你的眼睛。降低屏幕亮度也有助于节省电力并延长笔记本电脑的电池寿命。 除了手动更改屏幕亮度外,Windows还可以通过多种方式自动更改屏幕…

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm)

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm) 常见的归一化操作有&#xff1a;批量归一化&#xff08;Batch Normalization&#xff09;、层归一化&#xff08;Layer Normalization&#xff09;、实例归一化&#xff08;Instance Normaliza…

【React系列】React生命周期、setState深入理解、 shouldComponentUpdate和PureComponent性能优化、脚手架

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 生命周期 1.1. 认识生命周期 很多的事物都有从创建到销毁的整个过程&#xff0c;这个过程称之为是生命周期&…

案例分析——如何优化跨境直播网络

跨境直播 风口已至 这些年越来越多商家加入直播带货行列&#xff0c;各种玩法日渐成熟。而TikTok作为当前国外最火爆的直播平台&#xff0c;不少卖家都会定期做TikTok直播引流&#xff0c;但时常会面临着远程访问导致直播画面模糊、卡顿掉线、延迟高&#xff0c;甚至可能限流黑…

Django 4.2.7 ORM 连接MySQLServer 完成单表CRUD

文章目录 Django ORM介绍1.使用pycharm新建一个Django项目2.修改settings.py文件中 DATABASES3.创建APP4.创建模型5.操作数据库 Django ORM介绍 Django 模型使用自带的 ORM。 对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称 ORM &#xff09;用于实现面向…