代码随想录算法学习心得 51 | 503、下一个更大的元素II 42、接雨水...

news2024/11/27 6:10:57

一、下一个更大元素II

链接:力扣

描述如下:给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素

数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。


思路如下:

分两个思路,就是将原数组进行拼块,两个拼一起。还有就是处理循环数组。将两个nums数组拼接在一起,使用单调栈计算出每一个元素的下一个最大值,最后再把结果集即result数组resize到原数组大小就可以了。

循环数组的处理方式:

代码如下:

第一种思路:

class Solution {
public:
    //需要去遍历成环的数组,将两个数组合起来
    //可采用扩展数组的方式来实现
    vector<int> nextGreaterElements(vector<int>& nums) 
    {
        //存放结果
        vector<int>result(2*nums.size(),-1);
        vector<int>temp(nums.begin(), nums.end());//扩展后的数组
        for (int i = 0; i < nums.size(); i++)
        {
            temp.push_back(nums[i]);
        }
        stack<int>st;//单调栈
        st.push(0);
        for (int i = 1; i < temp.size(); i++)
        {
            if (temp[i] < temp[st.top()])
            {
                st.push(i);
            }
            else if (temp[i] == temp[st.top()])
            {
                st.push(i);
            }
            else
            {
                while (!st.empty() && temp[st.top()] < temp[i])
                {
                    int index = st.top();
                    result[index] = temp[i];
                    st.pop();
                }
             }
            st.push(i);
        }
        result.resize(nums.size());
        return result;
    }
};

第二种思路:

class Solution {
public:
    //需要去遍历成环的数组,将两个数组合起来
    //可采用扩展数组的方式来实现
    vector<int> nextGreaterElements(vector<int>& nums)
    {
        //不用扩充数组的方式
        stack<int>st;//单调栈
        vector<int>result(nums.size(), -1);
        st.push(0);
        for (int i = 1; i < 2 * nums.size(); i++)
        {
            int index = st.top();
            if (nums[i%nums.size()] < nums[index])
            {
                st.push(i % nums.size());
            }
            else if (nums[i % nums.size()] == nums[index])
            {
                st.push(i % nums.size());
            }
            else
            {
                while (!st.empty() && nums[i % nums.size()] > nums[st.top()])
                {
                    result[st.top()] = nums[i % nums.size()];
                    st.pop();
                }
                st.push(i % nums.size());
            }   
        }
        return result;
    }
};

 运行如下:


二、接雨水

链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

描述如下:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。


思路如下:

接雨水这道题目,需要寻找一个元素,右边最大元素以及左边最大元素,来计算雨水面积。

本题使用单调栈有如下几个问题:

1、首先单调栈是按照行方向来计算雨水,如图:

42.接雨水2

2、使用单调栈内元素的顺序

从大到小还是从小到大呢?从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。

因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。

如图:

42.接雨水4

3、遇到相同高度的柱子怎么办。

遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。

例如 5 5 1 3 这种情况。如果添加第二个5的时候就应该将第一个5的下标弹出,把第二个5添加到栈中。

因为要求宽度的时候 如果遇到相同高度的柱子,需要使用最右边的柱子来计算宽度

如图所示:

42.接雨水5

 

4、栈里要保存什么数值

使用单调栈,也是通过 长 * 宽 来计算雨水面积的。

长就是通过柱子的高度来计算,宽是通过柱子之间的下标来计算,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。

所以栈的定义如下:

stack<int> st; // 存着下标,计算的时候用下标对应的柱子高度

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

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 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++)

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

代码如下:

if (height[i] < height[st.top()])  st.push(i);

如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。

代码如下:

else if (height[i] == height[st.top()]) { 
  st.push(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(vector<int>& height) 
    {
        if (height.size() == 0)
        {
            return 0;
        }
        stack<int>st;//单调栈
        st.push(0);
        int result = 0;//记录雨水的面积
        for (int i = 1; i < height.size(); i++)
        {
            if (height[st.top()] > height[i])
            {
                st.push(i);
            }
            if (height[st.top()] == height[i])
            {
                st.push(i);
            }
            else
            {
                //记录中间位置
                while (!st.empty() && height[st.top()] < height[i])
                {
                    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;//宽度
                        result += h * w;
                    }               
                }
                st.push(i);
            }      
        }
        return result;
    }
};

运行如下:

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

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

相关文章

2023年五款免费高效的在线客服系统大揭秘!

近年来&#xff0c;随着移动互联网的蓬勃发展&#xff0c;企业与消费者之间的互动方式正在迅速演变&#xff0c;从传统的PC端转向了更加便捷灵活的移动端。在这个变革的大背景下&#xff0c;为了满足日益增长的客户需求&#xff0c;企业对于提供优质客户服务的迫切需求也逐渐凸…

【雕爷学编程】Arduino动手做(09)---火焰传感器模块4

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

基于时态差分法的强化学习:Sarsa和Q-learning

时态差分法&#xff08;Temporal Difference, TD&#xff09;是一类在强化学习中广泛应用的算法&#xff0c;用于学习价值函数或策略。Sarsa和Q-learning都是基于时态差分法的重要算法&#xff0c;用于解决马尔可夫决策过程&#xff08;Markov Decision Process, MDP&#xff0…

LoadRunner(2)

一、Controller 1.1场景设计 1.通过VUG打开 施压机器&#xff1a;发起请求的角色(用户本地电脑) 被压机器&#xff1a;处理请求的角色(服务器) 2.直接双击Controller 场景设计&#xff1a;需要关注三个部分 第一部分&#xff1a; 第二部分&#xff1a; 2.1运行场景…

11-数据结构-栈和队列的应用(C语言)

栈和队列的应用 目录 栈和队列的应用 一、括号匹配&#xff08;栈&#xff09; 二、表达式的各种转换 (1)中缀转后缀(手工) (2)后缀转中缀表达式(手工) (3)中缀转后缀(栈) (4)中缀转后缀&#xff08;树&#xff09; (5)后缀表达式求值 (6)中缀表达式求值&#xff08;栈…

2023杭电多校第8场J题-Rikka with Square Numbers

题目链接&#xff1a;csoj | J. Rikka with Square Numbers (scnu.edu.cn) 题目解析&#xff1a; 代码如下&#xff1a; #include<iostream> #include<math.h> #include<algorithm> using namespace std;int main() {ios::sync_with_stdio(0);cin.tie(0);c…

如何通过CSS选择器选择一个元素的子元素?如何选择第一个子元素和最后一个子元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 选择一个元素的子元素⭐ 选择第一个子元素和最后一个子元素⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…

【C语言】小游戏-三字棋

大家好&#xff0c;我是深鱼~ 目录 一、游戏介绍 二、文件分装 三、代码实现步骤 1.制作简易游戏菜单 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑随机下棋 6.判断输赢 7.判断棋盘是否满了 四、完整代码 game.h(相关函数的声明&#xff0c;整个代码要引用的头文件以及宏…

五金仓库的管理数字化

随着信息技术的快速发展&#xff0c;数字化管理在各行各业中迅速普及。数字化管理可以让企业轻松高效地收集、存储和共享数据&#xff0c;并利用大数据分析和人工智能等工具进行精确分析和预测&#xff0c;从而更好地理解业务运作情况并做出相应调整&#xff0c;以提高企业效率…

已有公司将ChatGPT集成到客服中心以增强用户体验

Ozonetel正在利用ChatGPT来改善客户体验。该公司表示&#xff0c;他们通过使用ChatGPT收集与客户互动过程收集的“语料”能够更有针对性地提高服务效率&#xff0c;提供个性化的用户体验&#xff0c;并实现更高的客户满意度。[1] 通过这套解决方案&#xff0c;客服中心将拥有一…

IDEA之Debug调试

资料来源于韩老师视频 &#xff08;一&#xff09;初探debug 1、打断点的话&#xff1a;直接在该行前面单击左键&#xff0c;出现小红点就是断点了。 想要取消断点的话&#xff0c;再单击小红点即可。 运行debug时&#xff0c;右键选择"Debug…"而不是选“Run…”…

sip语音对讲终端怎么样?

sip语音对讲终端怎么样&#xff1f; IP语音对讲终端是一种通过网络进行语音通信的设备&#xff0c;具有以下特点&#xff1a; 1. 便捷性&#xff1a;IP语音对讲终端可以通过互联网实现远程通信&#xff0c;用户可在任何地点与他人进行语音交流&#xff0c;无需受到距离的限制…

MySql011——检索数据:过滤数据(使用正则表达式)

前提&#xff1a;使用《MySql006——检索数据&#xff1a;基础select语句》中创建的products表 一、正则表达式介绍 关于正则表达式的介绍大家可以看我的这一篇博客《Java038——正则表达式》&#xff0c;这里就不再累赘。 二、使用MySQL正则表达式 2.1、基本字符匹配 检索…

18-有假币

题目 居然有假币&#xff01; 现在猪肉涨了&#xff0c;但是农民的工资却不见涨啊&#xff0c;没钱怎么买猪肉啊。nowcoder这就去买猪肉&#xff0c;结果找来的零钱中有假币&#xff01;&#xff01;&#xff01;可惜nowcoder 一不小心把它混进了一堆真币里面去了。只知道假币…

Java项目-苍穹外卖-Day03

员工分页查询功能实现 需求分析和设计 代码开发 先设计类 将对应分页查询的传参类以及结果类进行封装 对应真正返回的为Result<PageResult>Controller /**** param employeePageQueryDTO* return*/GetMapping("/page")ApiOperation("员工分页查询&qu…

【C++】开源:glog日志库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍glog日志库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次…

Mac M1 安装Oracle Java 与 IEDA

文章目录 1 官网下载2 安装IDEA参考 1 官网下载 https://www.oracle.com/ 使用finder中的拖拽进行安装即可 2 安装IDEA https://www.jetbrains.com/zh-cn/idea/download/?sectionmac 同样的&#xff0c;下载完后拖拽安装即可 参考 Mac M1 安装Java 开发环境 https://blog.…

Cmder:从此告别记事本记命令的日子

前言 平时开发中遇到这样那样的命令需要记下来&#xff0c;一般做法是这样。 新建记事本将需要记下的关键命令保存。每次需要使用时&#xff0c;粘贴复制即可。 好像没什么毛病&#xff01;直到遇到了 Cmder。。。 当看到同事分析问题时在 Cmder 里命令快捷键刷刷一顿操作&…

体渲染原理及WebGL实现【Volume Rendering】

体渲染&#xff08;Volume Rendering&#xff09;是NeRF神经场辐射AI模型的基础&#xff0c;与传统渲染使用三角形来显示 3D 图形不同&#xff0c;体渲染使用其他方法&#xff0c;例如体积光线投射 (Volume Ray Casting)。本文介绍体渲染的原理并提供Three.js实现代码&#xff…

【AI底层逻辑】——篇章7(上):海量运算背后的算力支持

目录 引入 一、计算机芯片 1、芯片的制造 2、复杂指令集&精简指令集 3、并行计算的GPU 二、协作计算 1、分布式技术“三论文” 2、不可兼得的CAP定理 3、故障类型 续下篇... 往期精彩&#xff1a; 引入 早在2016年DeepMind就公布了AlphaGo的算法细节&#xff0…