文章目錄
- 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;}
};