代码随想录算法训练营day59|第十章 单调栈part02

2024-03-14 04:36

本文主要是介绍代码随想录算法训练营day59|第十章 单调栈part02,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

503.下一个更大元素II 

42. 接雨水  


 

503.下一个更大元素II 

这道题和 739. 每日温度 几乎如出一辙,可以自己尝试做一做

 

代码随想录

这道题可以直接拼接数组,但是显然使用取余运算更划算。注意这回 i 代表的不直接是nums的下标,而更多的是遍历次数,取余之后才会是nums下标。还有文章里面给出的for的循环次数是nums.size()*2-1,而实际上可以是nums.size()*2-2,因为之所以要遍历两遍nums,是为了让所有的元素找临近较大值的时候可以从它的左边转一圈找到它的右边,所以针对最后后一个元素的寻找(其他元素早就满足这种寻找了),可以不遍历最后一个元素本身。

vector<int> nextGreaterElements(vector<int>& nums) {stack<int> st;vector<int> res(nums.size(),-1);st.push(0);for(int i=1;i<nums.size()*2-1;i++){while(st.size()&&nums[i%nums.size()]>nums[st.top()]){res[st.top()]=nums[i%nums.size()];st.pop();}st.push(i%nums.size());}return res;}

42. 接雨水  

接雨水这道题目是 面试中特别高频的一道题,也是单调栈 应用的题目,大家好好做做。建议是掌握 双指针 和单调栈,因为在面试中 写出单调栈可能 有点难度,但双指针思路更直接一些。在时间紧张的情况有,能写出双指针法也是不错的,然后可以和面试官在慢慢讨论如何优化。 

代码随想录

这道题使用双指针的思路其实是遍历两遍height数组,分别找到它的右边最高的柱子和左边最高的柱子,然后取这两个的最小值,这个值就是填满水之后应该达到的高度,如果这个高度是正值那就加上,反之说明不合法则不予理会,以此来求当前下标处增加的水量。

遍历求右边最高柱子的时候要从右往左遍历,如果当前的柱子高度小于历史最高柱子的高度,那就把历史最高柱子高度赋值给它,反之如果大于,那就证明当前柱子的右边没有比它更高的柱子了,于是这个下标处也不会盛水,所以为了依旧套用递推公式,这个地方应该赋值为当前柱子的高度(在使用递推公式推导的时候,需要求最小值,这个最小值有可能是当前柱子的高度,那么计算出来值就会是0,而如果是最左边柱子的高度,那么这个值就会是负数,而因为不合法,所以不被加入)。于是推导公式就简化为取当前柱子高度和历史柱子最高高度的最大值。求左边最高柱子数组差不多一个道理,只是需要倒序遍历。注意,可以事先设置这个最大高度为0,然后遍历就可以从两端开始,或者也可以直接把两端的值设置为两端柱子的高度,这样可以少遍历一个值,其实大差不差。

b5f475ca069b4318ac336879f69547c6.png

int trap(vector<int>& height) {if (height.size() <= 2) return 0;vector<int> maxLeft(height.size(), 0);vector<int> maxRight(height.size(), 0);int size = maxRight.size();// 记录每个柱子左边柱子最大高度maxLeft[0] = height[0];for (int i = 1; i < size; i++) {maxLeft[i] = max(height[i], maxLeft[i - 1]);}// 记录每个柱子右边柱子最大高度maxRight[size - 1] = height[size - 1];for (int i = size - 2; i >= 0; i--) {maxRight[i] = max(height[i], maxRight[i + 1]);}// 求和int sum = 0;for (int i = 0; i < size; i++) {int count = min(maxLeft[i], maxRight[i]) - height[i];if (count > 0) sum += count;}return sum;}

这道题使用单调栈做法也比较复杂,因为单调栈每次会弹出一些元素,所以不能像双指针做法那样按列来求,而是要一行一行的求,也就是除了求增加水量的高度之外,还要求增加水量的宽度(上一题直接求高度代表水量是因为宽度默认为1了)。

每次如果遍历到大于栈顶元素的值,那就先记录一下当前的栈顶元素,然后再弹出这个栈顶元素,然后再判断一下这个栈里面是否还剩有元素,如果剩有元素,证明可能构成一个凹槽用来盛水,那就要计算盛水的水量,先计算水的高度,水的高度取遍历的柱子的高度和栈顶高度的最小值再减去之前储存的那个栈顶元素,水的宽度当然就是遍历的元素的下标和现在栈顶元素的下标的下标差再减一(因为求的是中间的部分,用来盛水的那种宽度),相乘求得水量;而如果没有元素剩余,那就证明不能盛水。无论能否盛水,都需要将当前元素压入栈,以便后来的判断。如果遍历到小于等于栈顶元素的值,那就直接压入栈。

其实便利到等于栈顶元素的值有两种处理方法,第一种方法是直接压入栈中,然后按上面的做法来处理;另一种做法是舍弃掉这个元素,其实就算不舍弃压入栈中,最后公式计算得到的增加水量也是零,所以没什么太大差别。

afe86d9a5d7e46df9c4a658a30758479.png

int trap(vector<int>& height) {stack<int> st;st.push(0);int sum = 0;for (int i = 1; i < height.size(); i++) {while (!st.empty() && height[i] > height[st.top()]) {int mid = st.top();st.pop();if (!st.empty()) {int h = min(height[st.top()], height[i]) - height[mid];int w = i - st.top() - 1;sum += h * w;}}st.push(i);}return sum;}

 

 

这篇关于代码随想录算法训练营day59|第十章 单调栈part02的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807205

相关文章

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

nginx-rtmp-module模块实现视频点播的示例代码

《nginx-rtmp-module模块实现视频点播的示例代码》本文主要介绍了nginx-rtmp-module模块实现视频点播,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录预置条件Nginx点播基本配置点播远程文件指定多个播放位置参考预置条件配置点播服务器 192.

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下