739. 每日温度
链接:代码随想录
今天正式开始单调栈,这是单调栈一篇扫盲题目,也是经典题。
大家可以读题,思考暴力的解法,然后在看单调栈的解法。 就能感受出单调栈的巧妙
fvfdvsf
第一遍写错:
class Solution { public: vector<int> dailyTemperatures(vector<int>& temperatures) { int n=temperatures.size(); vector<int>res; if(n==1) { res.push_back(0); return res; } stack<int>st; st.push(0); for(int i=1;i<n;i++) { if(temperatures[i]<=temperatures[st.top()]) { st.push(i); } else { while(!st.empty() && temperatures[i]>temperatures[st.top()]) { res.push_back(i-st.top()); st.pop(); } st.push(i); } } return res; } };主要出错点分析:
按照这个代码去写,因为栈pop出来是逆序的,所以res 加入的index也是部分逆序的,不符合题目要求。
正确写法
class Solution { public: vector<int> dailyTemperatures(vector<int>& temperatures) { int n=temperatures.size(); vector<int>res(n,0); if(n==1) { return res; } stack<int>st; st.push(0); for(int i=1;i<n;i++) { if(temperatures[i]<=temperatures[st.top()]) { st.push(i); } else { while(!st.empty() && temperatures[i]>temperatures[st.top()]) { res[st.top()]=i-st.top(); st.pop(); } st.push(i); } } return res; } };
496.下一个更大元素 I
链接:代码随想录
本题和 739. 每日温度 看似差不多,其实 有加了点难度。
这个整个的逻辑有点绕,到底要不要创建map?map的定义装什么?为了便于理解,我定义了map,遍历nums2中的单调栈,map的第一个元素是nums2中的元素,第二个元素储存nums2中每个元素对应的下一个元素。然后最终修改nums1.看nums1中的每个元素在不在map中,从而找到对应的下一个元素。
class Solution { /* 如果计算nums2中所有元素的下一个元素,会造成时间和空间的浪费,但是又必须计算 */ public: vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) { int n1=nums1.size(); int n2=nums2.size(); unordered_map<int,int>um;//存储nums2中所有的下一个元素 stack<int>s; s.push(nums2[0]); for(int i=1;i<n2;i++) { if(nums2[i]<s.top()) { s.push(nums2[i]); } else { while(!s.empty()&& nums2[i]>s.top()) { um.insert(make_pair(s.top(),nums2[i])); s.pop(); } s.push(nums2[i]); } } //打印看一下um for(auto p :um) { cout<<p.first<<" "<<p.second<<endl; } //没问题,开始看对照um表返回,看nums1中的数 for(auto &p:nums1) { if(um.find(p)!=um.end()) { p=um[p]; } else { p=-1; } } return nums1; } };
503.下一个更大元素II
链接:代码随想录
因为太好奇了忍不住提前做了。怎样层层递进加入难度的。
我记得的,这个要把数组*2,或者使用%。以前做过,现在不记得咋做的了。
如果不存在循环着找,那这道题的答案是:
class Solution { public: //因为不涉及index,可以直接把数组扩展为原来的两倍,要么考虑(i+k)%n vector<int> nextGreaterElements(vector<int>& nums) { int n=nums.size(); stack<int>s; s.push(nums[0]); vector<int>res(n,-1);//储存下一个最大元素 for(int i=1;i<n;i++) { if(nums[i]<=s.top()) { s.push(nums[i]); } else { while(!s.empty() && nums[i]>s.top()) { res[i-1]=nums[i]; s.pop(); } s.push(nums[i]); } } /*for(auto p : res) { cout<<p<<" "; } cout<<endl;*/ return res; } };打印结果:
注意代码:
最后的代码: 理解起来还是比较抽象:
class Solution { public: //一般是通过 % 运算符求模(余数),来模拟环形特效 /* 所谓环形数组: 利用%n进行 while(1) { cout<<nums[index%n]<<endl; index++; } */ vector<int> nextGreaterElements(vector<int>& nums) { int n=nums.size(); /*这道题基本最边界的情况:最后一个元素找下一个最大元素,结果在它的左边找到了。所以基本只要 遍历两遍,就能得到答案 */ stack<int>st; vector<int>res(n,-1); st.push(0); for(int i=1;i<2*n;i++) { int index=i%n; if(nums[index]<=nums[st.top()]) { st.push(index); } else { while(!st.empty()&& nums[index]>nums[st.top()]) { res[st.top()]=nums[index]; st.pop(); } st.push(index); } } return res; } };
文章通过三个编程题目介绍了单调栈的应用,包括739.每日温度、496.下一个更大元素I和503.下一个更大元素II。在每日温度问题中,用单调栈找到每个温度后面第一个比它高的温度;在下一个更大元素问题中,利用单调栈查找数组中每个元素后面的更大元素,同时讨论了优化方法。503题进一步探讨了环形数组的情况,如何找到每个元素的下一个最大值。





我记得的,这个要把数组*2,或者使用%。以前做过,现在不记得咋做的了。

351

被折叠的 条评论
为什么被折叠?



