739. 每日温度
用数组模拟栈,tt指向栈顶。
从尾部开始遍历,如果当前温度大于等于栈顶的温度就把栈顶温度删了,因为再往前的元素比它大的最近的都不可能是这个。
如果栈有元素,取出下标与当前下标做差
最后把该下标放入栈中
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n=temperatures.size();
vector<int> answer(n,0);
int stk[100005],tt=0;
for(int i=n-1;i>=0;i--)
{
while(tt&&temperatures[i]>=temperatures[stk[tt]])tt--;
if(tt)answer[i]=stk[tt]-i;
stk[++tt]=i;
}
return answer;
}
};
496. 下一个更大元素 I
对于这题我们先遍历nums2数组,把每一个元素最右边的更大值存进哈希表里,再遍历一遍nums1数组即可。
stk依旧用数组模拟栈,然后遍历一遍nums2,栈中存目前为止的较大元素,如果栈不为空存入哈希表里,否则哈希表里存-1,把当前元素加入栈中。
遍历一遍nums1,把哈希表里对应的值取出来放入答案中。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
int l1=nums1.size(),l2=nums2.size();
unordered_map<int,int> m;
vector<int>ant;
int stk[1005],tt=0;
for(int i=l2-1;i>=0;i--)
{
while(tt&&nums2[i]>=stk[tt])tt--;
if(tt)m[nums2[i]]=stk[tt];
else m[nums2[i]]=-1;
stk[++tt]=nums2[i];
}
for(int i:nums1)
ant.push_back(m[i]);
return ant;
}
};
503. 下一个更大元素 II
这道题先遍历一遍数组,初始化一下单调栈,再从尾部往前遍历一遍,更新答案,栈不为空就放入栈中
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int l=nums.size();
vector<int>ant(l);
int stk[10005],tt=0;
for(int i=l-1;i>=0;i--)
{
while(tt&&nums[i]>=stk[tt])tt--;
stk[++tt]=nums[i];
}
for(int i=l-1;i>=0;i--)
{
while(tt&&nums[i]>=stk[tt])tt--;
if(tt)ant[i]=stk[tt];
else ant[i]=-1;
stk[++tt]=nums[i];
}
return ant;
}
};
42. 接雨水
这里采用两次遍历,找每个位置左右两边的最大高度,注意不是最近的比它大的高度,然后算一下两边位置的较小值,与height[i]做差加到answer中
class Solution {
public:
int trap(vector<int>& height) {
int answer=0;
int n=height.size();
vector<int> left(n+5,-1),right(n+5,-1);
vector<int> stk(n+5);int tt=0;
for(int i=0;i<n;i++)
{
while(tt&&height[i]>=stk[tt])tt--;
if(tt)left[i]=stk[tt];
else stk[++tt]=height[i];
}
tt=0;
for(int i=n-1;i>=0;i--)
{
while(tt&&height[i]>=stk[tt])tt--;
if(tt)right[i]=stk[tt];
else stk[++tt]=height[i];
}
for(int i=1;i<=n-2;i++)
{
int t=min(left[i],right[i]);
if(t>0)answer+=t-height[i];
}
return answer;
}
};
84. 柱状图中最大的矩形
这道题也是用两边单调栈,但跟上一题有略微的小调整,栈里存下标,并且处理方式也不一样,这里是较小栈。
最后遍历算面积取最大值即可
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
vector<int> left(n),right(n);
int ant=0; int stk[100005],tt=0;
for(int i=0;i<n;i++)
{
while(tt&&heights[i]<=heights[stk[tt]])tt--;
if(tt)left[i]=stk[tt];
else left[i]=-1;
stk[++tt]=i;
}
tt=0;
for(int i=n-1;i>=0;i--)
{
while(tt&&heights[i]<=heights[stk[tt]])tt--;
if(tt)right[i]=stk[tt];
else right[i]=n;
stk[++tt]=i;
}
for(int i=0;i<n;i++)
{
ant=max(ant,(right[i]-left[i]-1)*heights[i]);
}
return ant;
}
};