单调栈算法笔记
单调栈
定义: 单调栈就是栈内元素递增或者单调递减的栈,并且只能在栈顶操作。单调栈的维护是O(n)的时间复杂度,所有元素只会进进栈一次
性质:
- 单调栈里面的元素具有单调性;
- 元素加入栈前会把栈顶破坏单调性的元素删除;
- 使用单调栈可以找到元素向左遍历的第一个比他小的元素(单增栈),也可以找到元素向左遍历第一个比他大的元素(单减栈);
- 一般使用单调栈的题目具有以下的两点:
- 离自己最近(栈的后进先出的性质)
- 比自己大(小)、高(低);
注意:虽然称作是递增递减栈,但是实际存储的值并不是单调的,因为可以存坐标,只有坐标带入数组才是单调的。这样既可以存储数组的值,也可以存储数组下标。如下面的2,3,4例题。
例题:
1、LeetCode 496. Next Greater Element I
class Solution { public: vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) { vector<int> res(nums1.size(),-1); unordered_map<int,int>map; stack<int>stk; for(int i = 0 ; i < nums2.size(); i++){ while(!stk.empty()&& nums2[i] > stk.top()){ map[stk.top()] = nums2[i]; stk.pop(); } stk.push(nums2[i]);
<span class="token punctuation">}</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> nums1<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>map<span class="token punctuation">[</span>nums1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> res<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> map<span class="token punctuation">[</span>nums1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span> <span class="token punctuation">}</span>
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
2、LeetCode 42. Trapping Rain Water
class Solution {
public:
int trap(vector<int>& height) {
int res = 0;
int n = height.size();
if(n <= 2)
return 0;
stack<int>stk;
for(int i = 0; i<n ; i++){
while(!stk.empty() && height[stk.top()] < height[i]){
int top = stk.top();
stk.pop();
if(stk.empty())
break;
res += min(height[i] - height[top],height[stk.top()] - height[top])*(i - stk.top()-1);
}
stk.push(i);
}
return res;
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3、LeetCode 84. Largest Rectangle in Histogram
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(!heights.size()) return 0;
int n = heights.size();
heights.push_back(-1);
int res = 0;
stack<int>ss;
for(int i = 0; i <= n ; i++){
while(ss.size() && heights[ss.top()] > heights[i]){
int top = ss.top();
ss.pop();
if(ss.size())
res = max(res, heights[top]*(i-ss.top()-1));
else
res = max(res , heights[top]*i);
}
ss.push(i);
}
return res;
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
class Solution {
public:
bool find132pattern(vector<int>& nums) {
int n = nums.size();
if(n < 3) return false;
stack<int>ss;
vector<int> right_min(n,INT_MAX);
//此层循环找出nums[i]右边第一个比它小的数
for(int i = n - 1; i >= 0 ; i--){
while(ss.size() && nums[i] > nums[ss.top()]){
right_min[i] = nums[ss.top()];
ss.pop();
}
ss.push(i);
}
int min = nums[0];
for(int i = 1; i < n ; i++){
if(nums[i-1] < min ){
min = nums[i-1];
}
if(nums[i] > right_min[i] && min < right_min[i])
return true;
}
return false;
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
其他使用单调栈的例题
参考博客:
</div><div><div></div></div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
</div>
来自leetcode的单调栈题目推荐: