单调栈的作用
就是用一个栈来记录我们遍历过的元素
单调栈里存放元素下标i就可以了,如果要使用对应元素,直接T[i]就可以获取到
从栈头到栈尾-递增的话-栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i
题目
LeetCode:739.每日温度
解法
将下标存放进单调栈中
当前遍历的元素和栈顶元素进行比较T[i]和T[st.pop()]
T[i]==T[st.pop()] 入栈
T[i]>T[st.pop()] 记录结果
T[i]<T[st.pop()] 入栈
class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {stack<int> st;vector<int> reulst(temperatures.size(),0);st.push(0);//放入第一个元素for(int i=1;i<temperatures.size();i++){if(temperatures[i]<temperatures[st.top()]) st.push(i);else if(temperatures[i]==temperatures[st.top()]) st.push(i);else{while(!st.empty()&&temperatures[i]>temperatures[st.top()]){reulst[st.top()]=i-st.top();st.pop();}st.push(i);}}return reulst;}
};
LeetCode:496.下一个更大
解法
class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {vector<int> result(nums1.size(),-1); //结果数组的长度与1相等stack<int> st;if(nums1.size()==0) return result;unordered_map<int,int> umap;//对数组1进行处理 建立哈希表for(int i=0;i<nums1.size();i++){umap[nums1[i]]=i;}//用单调栈遍历数组2st.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){int index=umap[nums2[st.top()]];result[index]=nums2[i];}st.pop();}st.push(i);}}return result;}
};
LeetCode:503.下一个更大元素II
用取模的过程模拟成环的遍历
for(i=0;i<nums.size()*2;i++){
i%nums.size()
}
class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {vector<int> result(nums.size(),-1);stack<int> st;st.push(0);//放入第一个元素for(int i=1;i<nums.size()*2;i++){if(nums[i%nums.size()]<=nums[st.top()]) 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:42.接雨水
class Solution {
public:int trap(vector<int>& height) {stack<int> st;st.push(0);int sum=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.pop();st.push(i);}//如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了else{while(!st.empty()&&height[i]>height[st.top()]){int mid=height[st.top()];st.pop();if(!st.empty()){int h=min(height[i],height[st.top()])-mid;int w=i-st.top()-1;sum+=h*w;}}st.push(i);}}return sum;}
};
LeetCode:84.柱状图中最大的矩形
class Solution {
public:int largestRectangleArea(vector<int>& heights) {int result=0;stack<int> st;heights.insert(heights.begin(), 0); // 数组头部加入元素0heights.push_back(0); // 数组尾部加入元素0st.push(0);for(int i=1;i<heights.size();i++){//循环//条件1 大于等于的情况if(heights[i]>=heights[st.top()]){st.push(i);}//条件2 小于的情况else{while(!st.empty()&&heights[i]<heights[st.top()]){int mid=st.top();st.pop();if(!st.empty()){int left=st.top();int right=i;int h=heights[mid];int w=right-left-1;result=max(result,w*h);}}st.push(i);}}return result;}
};
感觉是最难理解的一部分了&完结撒花