单调栈

思路:

1.确定单调减还是单调增,由出栈时的处理决定
2.是否加左/右哨兵根据具体问题,不加的话要对栈判空,可能最后需要处理栈中剩下的元素。
3.栈中存储下标的话能同时知道值

##模板
插入前后哨兵节点(可选)
入下标0
for 数组 [1:size()]:
    while(不符合单调栈){
        出栈,计算
    }
    入栈 

84. 最大矩形面积

#include <iostream>
#include <stack>
#include <vector>
#include <cstring>
using namespace std;

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.insert(heights.begin(),0); //需要两个哨兵的原因:1.计算面积需要看左右,加入哨兵不用判空 2.需要计算所有的值,最后加入的0保证栈最后为空
        heights.push_back(0);
        sk.push(0); //入栈的是下标   
        int max=0;
        for(int i=1;i<heights.size();i++)
        {
            int width=0;
          while(heights[i]<heights[sk.top()])
          {
                int topindex=sk.top();
                sk.pop();
                width = i- sk.top() -1; 它一左一右的两个柱形的下标的差就是这个面积最大的矩形对应的最大宽度。
                int area=width*heights[topindex];
                if(area>max)
                max=area;
          }
          sk.push(i);
        }
        return max;
    }

    stack<int> sk;
};



739. 每日温度

class Solution {
public:
  vector<int> dailyTemperatures(vector<int> &T) 
  {
    vector<int> res(T.size(), 0);

    sk.push({30001, -1});
    for (int i = 0; i < T.size(); i++) {
      if (T[i] <= sk.top().t) {
        sk.push({T[i], i});
      } else {
        while (T[i] > sk.top().t) {

          res[sk.top().index] = i - sk.top().index;
          sk.pop();
        }
        sk.push({T[i], i});
      }
    }

    return res;
  }
  struct Node {
    int t;
    int index;
  };
  stack<Node> sk;
};

503. 下一个更大元素

struct Node
{
    int index;
    int num;
};
class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> res(2*nums.size(), -1);
        int originNum = nums.size();
        for(int i = 0;i < originNum;i++)
        {
            nums.push_back(nums[i]);
        }
        for(int i = 0;i<nums.size();i++) {
            if(sk.empty()||nums[i]<=sk.top().num)
            {
                sk.push({i,nums[i]});
            } else {
                while(!sk.empty()&&nums[i]>sk.top().num) {

                
                int indextop = sk.top().index;
                sk.pop();
                res[indextop] = nums[i];
                }
                sk.push({i,nums[i]});
            }
            
        }
        vector<int> res2;
        for(int i =0 ;i<originNum;i++)
        {
            res2.push_back(res[i]);
        }
        return res2;
    }
    stack<Node> sk;
};

85. 最大矩形

class Solution
{
public:
    int maximalRectangle(vector<vector<char>> &matrix)
    {
        if(matrix.size()==0||matrix[0].size()==0)
        {
            return 0;
        }
        int rows = matrix.size();
        int cols = matrix[0].size();
        int max = 0;
        vector<int> height(cols + 2, 0); //哨兵
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                height[j + 1] = matrix[i][j] == '0' ? 0 : 1 + height[j + 1];
            }
            stack<int> sk;
            sk.push(0);
            for (int k = 1; k < height.size(); k++)
            {
                int width = 0;
                while (height[k] < height[sk.top()])
                {
                    int topindex = sk.top();
                    sk.pop();
                    width = k - sk.top() - 1;
                    int area = width * height[topindex];
                    if (area > max)
                        max = area;
                }
                sk.push(k);
            }
        }
        return max;
    }
};

42. 接雨水

class Solution
{
public:
    int trap(vector<int> &height)
    {

        sk.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++)
        {
            
                while (!sk.empty() && height[i] > height[sk.top()])
                {
                    int tempindex = sk.top();
                    sk.pop();
                    int tempheight = 0;
                    if (!sk.empty())
                    {
                        tempheight = min(height[sk.top()], height[i]) - height[tempindex];
                    }
                    else
                    {
                        break;
                    }
                    int width = 0;
                    if (!sk.empty())
                        width = i - sk.top() - 1;
                    sum += width * tempheight;
                }
                sk.push(i);
            
        }
        return sum;
    }
    stack<int> sk;
};
原文地址:https://www.cnblogs.com/void-lambda/p/13721073.html