代码随想录算法训练营day58 | 单调栈 739. 每日温度 496.下一个更大元素 I
创始人
2024-06-02 16:12:52
0

day58

      • 739. 每日温度
        • 1.单调栈里存放的元素是什么?
        • 2.单调栈里元素是递增呢? 还是递减呢?
      • 496.下一个更大元素 I

739. 每日温度

题目链接
解题思路: 单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

更直白来说,就是用一个栈来记录我们遍历过的元素,因为我们遍历数组的时候,我们不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。

在使用单调栈的时候首先要明确如下几点:

1.单调栈里存放的元素是什么?

单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。

2.单调栈里元素是递增呢? 还是递减呢?

注意以下顺序的描述为 从栈头到栈底的顺序

这里要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i

即:如果求一个元素右边第一个更大元素,单调栈就是递增的,如果求一个元素右边第一个更小元素,单调栈就是递减的。

文字描述理解起来有点费劲,接下来我画了一系列的图,来讲解单调栈的工作过程,大家再去思考,本题为什么是递增栈。

使用单调栈主要有三个判断条件。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

把这三种情况分析清楚了,也就理解透彻了。

接下来我们用temperatures = [73, 74, 75, 71, 71, 72, 76, 73]为例来逐步分析,输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]

首先先将第一个遍历元素加入单调栈
在这里插入图片描述
加入T[1] = 74,因为T[1] > T[0](当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况)。

我们要保持一个递增单调栈(从栈头到栈底),所以将T[0]弹出,T[1]加入,此时result数组可以记录了,result[0] = 1,即T[0]右面第一个比T[0]大的元素是T[1]

在这里插入图片描述加入T[2],同理,T[1]弹出
在这里插入图片描述加入T[3]T[3] < T[2] (当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况),加T[3]加入单调栈。
在这里插入图片描述加入T[4]T[4] == T[3] (当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况),此时依然要加入栈,不用计算距离,因为我们要求的是右面第一个大于本元素的位置,而不是大于等于!
在这里插入图片描述加入T[5]T[5] > T[4] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[4]弹出,同时计算距离,更新result
在这里插入图片描述
T[4]弹出之后, T[5] > T[3] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[3]继续弹出,同时计算距离,更新result
在这里插入图片描述直到发现T[5]小于T[st.top()],终止弹出,将T[5]加入单调栈
在这里插入图片描述加入T[6],同理,需要将栈里的T[5]T[2]弹出
在这里插入图片描述同理,继续弹出
在这里插入图片描述
此时栈里只剩下了T[6]
在这里插入图片描述加入T[7]T[7] < T[6] 直接入栈,这就是最后的情况,result数组也更新完了。
在这里插入图片描述此时有同学可能就疑惑了,那result[6] , result[7]怎么没更新啊,元素也一直在栈里。

其实定义result数组的时候,就应该直接初始化为0,如果result没有更新,说明这个元素右面没有更大的了,也就是为0。

以上在图解的时候,已经把,这三种情况都做了详细的分析。

  • 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

通过以上过程,大家可以自己再模拟一遍,就会发现:只有单调栈递增(从栈口到栈底顺序),就是求右边第一个比自己大的,单调栈递减的话,就是求右边第一个比自己小的。

C++代码如下:

class Solution {
public:vector dailyTemperatures(vector& T) {// 递增栈stack st;vector result(T.size(), 0);st.push(0);for (int i = 1; i < T.size(); i++) {if (T[i] < T[st.top()]) {                       // 情况一st.push(i);} else if (T[i] == T[st.top()]) {               // 情况二st.push(i);} else {while (!st.empty() && T[i] > T[st.top()]) { // 情况三result[st.top()] = i - st.top();st.pop();}st.push(i);}}return result;}
};

496.下一个更大元素 I

题目链接
解题思路:
本题则是说nums1nums2 的子集,找nums1中的元素在nums2中下一个比当前元素大的元素。

看上去和上一题是一样的,但是这么绕了一下,其实还上升了一点难度。

需要对单调栈使用的更熟练一些,才能顺利的把本题写出来。

从题目示例中我们可以看出最后是要求nums1的每个元素在nums2中下一个比当前元素大的元素,那么就要定义一个和nums1一样大小的数组result来存放结果。

一些同学可能看到两个数组都已经懵了,不知道要定一个一个多大的result数组来存放结果了。

这么定义这个result数组初始化应该为多少呢?

题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。

在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。

注意题目中说是两个没有重复元素 的数组 nums1nums2

没有重复元素,我们就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。

C++中,当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的。我在关于哈希表,你该了解这些!

那么预处理代码如下:

unordered_map umap; // key:下标元素,value:下标
for (int i = 0; i < nums1.size(); i++) {umap[nums1[i]] = i;
}

使用单调栈,首先要想单调栈是从大到小还是从小到大。

本题和上一题一样的。

栈头到栈底的顺序,要从小到大,也就是保持栈里的元素为递增顺序。只要保持递增,才能找到右边第一个比自己大的元素。

可能这里有一些同学不理解,那么可以自己尝试一下用递减栈,能不能求出来。其实递减栈就是求右边第一个比自己小的元素了。

接下来就要分析如下三种情况,一定要分析清楚。

  • 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况

此时满足递增栈(栈头到栈底的顺序),所以直接入栈。

  • 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况

如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于!

  • 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。

判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。

记录结果这块逻辑有一点小绕,要清楚,此时栈顶元素在nums2数组中右面第一个大的元素是nums2[i](即当前遍历元素)。

代码如下:

while (!st.empty() && nums2[i] > nums2[st.top()]) {if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下标result[index] = nums2[i];}st.pop();
}
st.push(i);

以上分析完毕,C++代码如下:

class Solution {
public:vector nextGreaterElement(vector& nums1, vector& nums2) {stack st;vector result(nums1.size(), -1);if (nums1.size() == 0) return result;unordered_map umap; // key:下标元素,value:下标for (int i = 0; i < nums1.size(); i++) {umap[nums1[i]] = i;}st.push(0);for (int i = 1; i < nums2.size(); i++) {if (nums2[i] < nums2[st.top()]) {           // 情况一st.push(i);} else if (nums2[i] == nums2[st.top()]) {   // 情况二st.push(i);} else {                                    // 情况三while (!st.empty() && nums2[i] > nums2[st.top()]) {if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下标result[index] = nums2[i];}st.pop();}st.push(i);}}return result;}
};

相关内容

热门资讯

门口门禁安卓系统 开源,构建便... 你有没有想过,家里的门口也能变得智能起来呢?想象当你回家时,门禁系统自动识别你的脸庞,轻轻一笑,门就...
安卓系统调节音量吗,轻松掌控手... 手机里的声音总是那么调皮,有时候太吵,有时候又太小声,真是让人头疼。别急,今天就来教你如何轻松调节安...
安卓a和b系统,深度解析两大操... 亲爱的读者们,你是否曾好奇过安卓手机里的A和B系统究竟有何不同?今天,就让我带你一探究竟,揭开这个神...
pc安装安卓5.0系统,跨越设... 你有没有想过,把手机里的安卓系统搬到电脑上,那感觉是不是就像给电脑穿上了时尚的新衣?今天,就让我带你...
安卓系统手机怎么备份,全方位备... 亲爱的手机控们,你是否也有过这样的烦恼:手机里的照片、视频、联系人、应用等数据,突然间消失得无影无踪...
侧滑手机 安卓系统,安卓系统下... 你有没有想过,手机的世界里,曾经有一群特别的“舞者”?它们就是侧滑手机,尤其是那些搭载了安卓系统的宝...
安卓系统屏幕乱跳,安卓手机屏幕... 亲爱的手机控们,你们有没有遇到过这样的烦恼:手机屏幕突然开始乱跳,就像有只小手在屏幕上乱点乱划,让人...
元气骑士支持安卓系统,畅享奇幻... 哎呀呀,你知道吗?最近我在手机上发现了一款超级好玩的游戏,它就是《元气骑士》!这款游戏不仅画面萌萌哒...
mtk安卓系统手机驱动,MTK... 你有没有遇到过这种情况:手机连接电脑时,电脑就像个“瞎子”,怎么也看不见你的宝贝手机?别急,今天就来...
安卓项目系统设计总结,安卓项目... 你有没有想过,一个安卓项目从无到有,就像是一颗种子在土壤中慢慢生根发芽,最终长成参天大树呢?今天,就...
安卓系统绑定定位,智慧生活新体... 你有没有想过,手机这小玩意儿,不仅能打电话、发短信,还能变成你的私人侦探,随时随地告诉你朋友或家人的...
安卓如何清系统数据,轻松恢复流... 亲爱的手机控们,你们是不是也和我一样,时不时地觉得手机卡顿得厉害,就像老牛拉破车一样?别急,今天就来...
华为摆脱安卓系统了吗,全面摆脱... 你有没有听说最近华为的大动作?没错,就是那个让安卓系统都黯然失色的鸿蒙系统!是不是好奇华为是不是真的...
beats耳机蓝牙 安卓系统,... 你有没有想过,那些在街头巷尾随处可见,时尚潮人们必备的Beats耳机,竟然也能和你的安卓手机愉快地“...
安卓系统为什么要用linux系... 亲爱的读者们,你是否曾好奇过,为什么安卓系统会选择拥抱Linux系统呢?这背后可是有着不少故事哦!今...
qq飞车苹果系统转安卓系统,跨... 亲爱的飞车迷们,你们是不是也有过这样的烦恼:手机从苹果换成了安卓,可心爱的QQ飞车账号却无法带过去?...
小米安卓系统隐藏彩蛋,体验科技... 哇塞,你知道吗?小米安卓系统里竟然藏着不少隐藏彩蛋,就像宝藏一样等着我们去发掘!这些彩蛋不仅让人惊喜...
然如何看安卓系统,安卓系统下的... 亲爱的手机控们,你是否曾好奇过,自己手中的安卓手机究竟运行着哪个版本的操作系统呢?别急,今天就来带你...
安卓系统关闭锁频,享受自由畅快... 手机锁屏这事儿,是不是让你头疼过?每次解锁都要输入密码,有时候手忙脚乱,简直就像是在玩解谜游戏。别急...
奥迪安卓系统如何升级,轻松提升... 亲爱的奥迪车主们,你们是不是也和我一样,对那辆爱车的智能系统充满了好奇呢?今天,就让我来带你一起探索...