LeetCode单调栈经典题目(十)
创始人
2024-05-27 10:47:46

目录

1. LeetCode739. 每日温度

2. LeetCode496. 下一个更大元素 I

3. LeetCode503. 下一个更大元素 II

4. LeetCode42. 接雨水

5. LeetCode84. 柱状图中最大的矩形


在一维数组中,要寻找任一元素的右边或者左边第一个自己大或小的元素的位置,就可以想到用单调栈了。——代码随想录

1. LeetCode739. 每日温度

思路:
1.创建辅助栈stk和结果数组answer
2.遍历温度数组,把第i天的温度temperatures[i]入栈,栈顶到栈底单调递减
3.如果当前温度大于栈顶温度,则不断出栈,并把相隔天数(i-stk.top())写入到结果集中class Solution {
public:vector dailyTemperatures(vector& temperatures) {//结果集,因为对于后续没有温度更高的,结果是0,所以默认都为0vectoranswer(temperatures.size());//辅助栈stackstk;//遍历数组for(int i=0;itemperatures[stk.top()]){answer[stk.top()]=i-stk.top();stk.pop();}stk.push(i);//存入下标,既能知道天数,又可以知道温度}return answer;}
};时间复杂度:O(n),对于每个温度数组的元素下标,只有入栈和出栈各一次操作;
空间复杂度:O(n),需要维护一个辅助栈

2. LeetCode496. 下一个更大元素 I

思路:
1.创建辅助栈stk,结果集ans,映射表存储nums1中各元素和下标的对应
2.初始化结果集为-1
3.建立好nums1的映射关系
4.遍历nums2,找到nums1中的元素在nums2右边第一个比自己大的值,放入结果集中卡点:因为nums1和nums2是元素方面的联系,所以可以通过哈希表来找到当前遍历元素在nums1中的对应下标class Solution {
public:vector nextGreaterElement(vector& nums1, vector& nums2) {//结果集,默认-1vectorans(nums1.size(),-1);//辅助栈stackstk;//栈底到栈顶:单调递减//映射表unordered_maprecorded;//建立映射关系for(int i=0;inums2[stk.top()]){if(recorded.count(nums2[stk.top()])>0){ans[recorded[nums2[stk.top()]]]=nums2[i];}stk.pop();}stk.push(i);}return ans;}
};

3. LeetCode503. 下一个更大元素 II

class Solution {
public:vector nextGreaterElements(vector& nums) {vectorans(nums.size(),-1);//结果集,默认-1stackstk;//辅助栈,栈底到栈顶:单调递减//当第二次遍历到最大值时,就可以结束循环了//第一次遍历到最大值:后面的元素还没遍历到,需要继续处理//第二次遍历到最大值时,最坏情况下,后面的所有元素右边比自己更大的数刚好就是最大值//由于所有位置的元素都有可能是最大值,所以把所有元素都遍历两次,nums的所有元素肯定都处理好了for(int i=0;inums[stk.top()]){ans[stk.top()]=nums[i%nums.size()];stk.pop();}stk.push(i%nums.size());}return ans;}
};

4. LeetCode42. 接雨水

1.双指针:按列计算雨水面积
当前列的雨水面积=min(左边最大高度,右边最大高度)-当前列高度,因为宽度默认是1,取最小值是由于短板效应
因为我们只需要每一列柱子左边和右边的高度的最小值,所以可以用maxLeft和maxRight来记录,这样就避免了重复计算左右两边最大高度的操作
class Solution {
public:int trap(vector& height) {int res=0;//结果vectormaxLeft(height.size());//左边最大高度vectormaxRight(height.size());//右边最大高度//动态规划maxLeft[0]=height[0];for(int i=1;i=0;i--){maxRight[i]=max(maxRight[i+1],height[i]);}//计算雨水面积for(int i=1;i& height) {stackstk;//辅助栈int res=0;//结果stk.push(0);//先让0入栈,因为已进入循环就要和stk.top()比较,所以先让0入栈for(int i=1;iheight[stk.top()]){int mid=stk.top();stk.pop();if(!stk.empty()){int h=min(height[stk.top()],height[i])-height[mid];int w=i-stk.top()-1;res+=h*w;}}stk.push(i);}}return res;}
};简化代码:
等于和小于的操作类似,而等于的更新栈顶元素不影响计算。如果栈顶和栈顶的下一个元素相同,则在大于的操作中h=0,不影响结果。等到栈顶下一个相等高度的柱子做凹槽底部时,h是正常的,w也不受影响,因为w只和stk.top()有关,和弹出的柱子无关
class Solution {
public:int trap(vector& height) {stackstk;//辅助栈int res=0;//结果stk.push(0);for(int i=1;iheight[stk.top()]){int mid=stk.top();stk.pop();if(!stk.empty()){int h=min(height[stk.top()],height[i])-height[mid];int w=i-stk.top()-1;res+=h*w;}}stk.push(i);}return res;}
};卡点:没有考虑凹槽底部柱子高度,导致计算了很多多余的面积

5. LeetCode84. 柱状图中最大的矩形

1.双指针:
leftFirst[i]:0~i-1第一个比柱子i低的下标
rightFirst[i]:i+1~height.size()-1第一个比i低的下标
把leftFirst[0]初始化为-1,把rightFirst初始化为height.size(),能够最低的柱子计算出正确的矩形class Solution {
public:int largestRectangleArea(vector& heights) {int res=0;vectorleftFirst(heights.size());vectorrightFirst(heights.size());leftFirst[0]=-1;for(int i=1;i=0&&heights[i]<=heights[t])t=leftFirst[t];leftFirst[i]=t;   }rightFirst[heights.size()-1]=heights.size();for(int i=heights.size()-2;i>=0;i--){int t=i+1;while(theight[stk.top()]:入栈
height[i]==height[stk.top()]:更新栈顶
height[i]& heights) {stackstk;int res=0;heights.insert(heights.begin(),0);heights.push_back(0);stk.push(0);for(int i=1;iheights[stk.top()])stk.push(i);else if(heights[i]==heights[stk.top()])stk.top()=i;else{while(!stk.empty()&&heights[i]& heights) {stackstk;int res=0;heights.insert(heights.begin(),0);heights.push_back(0);stk.push(0);for(int i=1;i

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...