單調棧的定義
單調棧,顧名思義,是維持單調遞增或遞減的棧
單調棧的性質
單調遞增棧
單調遞增棧的形式如上,適合尋找,距離他最近的,比他小的,左右兩邊元素
單調遞減棧
與單調遞增棧的用法相反
題目
84. 柱狀圖中最大的矩形
單調遞增棧的原理
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0); // 添加0,便於處理
stack<int> st;
int ans = 0;
for(int i = 0; i < heights.size(); i++){ // 單調棧套路
while(!st.empty() && heights[i] <= heights[st.top()]){ // 單調棧套路
int tmp = heights[st.top()]; // 單調棧套路
st.pop(); // 單調棧套路
int area = st.empty() ? tmp*i : tmp * (i - st.top() - 1); // 處理邏輯
ans = max(ans, area); // 處理邏輯
}
st.push(i); // 單調棧套路
}
return ans;
}
};
42. 接雨水
單調遞減棧
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0;
stack<int> st;
for(int i = 0; i < height.size(); i++){
while(!st.empty() && height[i] > height[st.top()]){
int tmp = height[st.top()];
st.pop();
if(!st.empty()){
ans += (min(height[i], height[st.top()]) - tmp)*(i - st.top() - 1);
}
}
st.push(i);
}
return ans;
}
};
739. 每日溫度
這個題使用遞減棧
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
int size = T.size();
vector<int> ans(size, 0);
stack<int> st;
for(int i = 0; i < size; i++){
while(!st.empty() && T[i] > T[st.top()]){
ans[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
return ans;
}
};
496. 下一個更大元素 I
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> mp;
stack<int> st;
vector<int> ret(nums1.size(), -1);
for(int i = 0; i < nums1.size(); i++){
mp[nums1[i]] = i;
}
for(int i = 0; i < nums2.size(); i++){
while(!st.empty() && nums2[i] > nums2[st.top()]){
int val = nums2[st.top()];
if(mp.find(val) != mp.end()){
int index = mp[val];
ret[index] = i;
}
st.pop();
}
st.push(i);
}
return ret;
}
};