文章目录
- 503.下一个更大元素II
- 思路
- 代码
- 42. 接雨水
- 思路
- 代码
- 84.柱状图中最大的矩形
- 思路
- 代码
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); // 数组头部加入元素0heights.push_back(0); // 数组尾部加入元素0st.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()]) { // 注意是whileint 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;}
};