503.下一个更大元素II
题目链接:503.下一个更大元素II
文章讲解:代码随想录|503.下一个更大元素II
思路
和739. 每日温度 (opens new window)也几乎如出一辙,区别于在遍历的过程中模拟走两边nums
代码
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> result(nums.size(), -1);
if (nums.size() == 0) return result;
stack<int> st;
st.push(0);
for (int i = 1; i < nums.size() * 2; i++) {
// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
if (nums[i % nums.size()] < nums[st.top()]) st.push(i % nums.size());
else 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;
}
};
42. 接雨水
题目链接:42. 接雨水
文章讲解:代码随想录|42. 接雨水
思路
寻找右边第一个比自己大的元素,来计算雨水面积
单调栈是按行计算的
一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子
遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中
代码
class Solution {
public:
int trap(vector<int>& height) {
int result = 0;
stack<int> stk;
stk.push(0);
int mid, h, w;
for(int i = 1; i < height.size(); i++){
if(height[i] < height[stk.top()]) stk.push(i);
else if(height[i] == height[stk.top()]){
stk.pop();
stk.push(i);
}else{
while(!stk.empty() && height[i] > height[stk.top()]){
mid = stk.top();
stk.pop();
if (!stk.empty()) {
h = min(height[i], height[stk.top()]) - height[mid];
w = i - stk.top() - 1;
result += h * w;
}
}
stk.push(i);
}
}
return result;
}
};
stk.pop();后要记得判断if (!stk.empty()),因为有时候可能没有左边的柱子
84.柱状图中最大的矩形
题目链接:84.柱状图中最大的矩形
文章讲解:代码随想录|84.柱状图中最大的矩形
思路
- 接雨水 (opens new window)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。
只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。
代码
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int result = 0;
stack<int> st;
heights.insert(heights.begin(), 0); // 数组头部加入元素0
heights.push_back(0); // 数组尾部加入元素0
st.push(0);
// 第一个元素已经入栈,从下标1开始
for (int i = 1; i < heights.size(); i++) {
if (heights[i] > heights[st.top()]) { // 情况一
st.push(i);
} else if (heights[i] == heights[st.top()]) { // 情况二
st.pop(); // 这个可以加,可以不加,效果一样,思路不同
st.push(i);
} else { // 情况三
while (!st.empty() && heights[i] < heights[st.top()]) { // 注意是while
int mid = st.top();
st.pop();
if (!st.empty()) {
int left = st.top();
int right = i;
int w = right - left - 1;
int h = heights[mid];
result = max(result, w * h);
}
}
st.push(i);
}
}
return result;
}
};