[Algo] 单调栈
基本模板:
vector<vector<int>> lessThanIndex(vector<int> &arr)
{
int len = arr.size();
vector<vector<int>> ans(len, vector<int>(2, 0));
stack<int> s;
for (int i = 0; i < len; i++)
{
while (!s.empty() && arr[i] <= arr[s.top()])
{
int index = s.top();
s.pop();
ans[index][0] = s.empty() ? -1 : s.top();
ans[index][1] = i;
}
s.push(i);
}
while (!s.empty())
{
int index = s.top();
s.pop();
ans[index][0] = s.empty() ? -1 : s.top();
ans[index][1] = -1;
}
// 存在相等元素时,需要对ans[i][1]进行修正
for (int i = len - 1; i >= 0; i--)
{
if (ans[i][1] != -1 && arr[i] == arr[ans[i][1]]) ans[i][1] = ans[ans[i][1]][1];
}
return ans;
}
1. 柱状图中的最大矩形
// 1. 柱状图中的最大矩形
// https://leetcode.cn/problems/largest-rectangle-in-histogram/description/
int largestRectangleArea(vector<int>& heights) {
vector<vector<int>> v = lessThanIndex(heights);
int max_size = 0;
for (int i = 0; i < heights.size(); i++)
{
int l = v[i][0] == -1 ? 0 : v[i][0] + 1;
int r = v[i][1] == -1 ? heights.size() - 1 : v[i][1] - 1;
max_size = max(max_size, (r - l + 1) * heights[i]);
}
return max_size;
}
2. 最大矩形
// 2. 最大矩形
// https://leetcode.cn/problems/maximal-rectangle/description/
int maximalRectangle(vector<vector<char>>& matrix) {
int n = matrix.size(), m = matrix[0].size();
vector<int> heights(m, 0);
int max_size = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++) heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0;
max_size = max(max_size, largestRectangleArea(heights));
}
return max_size;
}
3. 最大宽度坡
// 3. 最大宽度坡
// https://leetcode.cn/problems/maximum-width-ramp/
int maxWidthRamp(vector<int>& nums) {
stack<int> s;
int len = nums.size(), ans = 0;
for (int i = 0; i < len; i++) if (s.empty() || nums[i] < nums[s.top()]) s.push(i);
for (int i = len - 1; i >= 0; i--)
{
while (!s.empty() && nums[i] >= nums[s.top()])
{
ans = max(ans, i - s.top());
s.pop();
}
}
return ans;
}
4. 去除重复字母,保证返回结果的字典序最小
// 4. 去除重复字母,保证返回结果的字典序最小
// https://leetcode.cn/problems/remove-duplicate-letters/
string removeDuplicateLetters(string s) {
unordered_map<char, int> letter;
for (char ch : s) letter[ch]++;
stack<char> stk;
unordered_set<char> set;
for (int i = 0; i < s.length(); i++)
{
letter[s[i]]--;
if (set.find(s[i]) != set.end()) continue;
while (!stk.empty() && s[i] <= stk.top() && letter[stk.top()] > 0)
{
set.erase(stk.top());
stk.pop();
}
stk.push(s[i]);
set.insert(s[i]);
}
string ans;
while (!stk.empty())
{
ans += stk.top();
stk.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
5. 统计全1子矩形
// 5. 统计全1子矩形
// https://leetcode.cn/problems/count-submatrices-with-all-ones/description/
int numMat(vector<int>& mat) {
int len = mat.size();
stack<int> s;
int ans = 0;
for (int i = 0; i < len; i++)
{
while (!s.empty() && mat[s.top()] >= mat[i])
{
int index = s.top();
s.pop();
if (mat[index] > mat[i])
{
int l = s.empty() ? -1 : s.top();
int r = i;
int width = (r - l) * (r - l - 1) / 2;
int lval = l == -1 ? 0 : mat[l];
int rval = mat[r];
int height = mat[index] - max(lval, rval);
ans += width * height;
}
}
s.push(i);
}
while (!s.empty())
{
int index = s.top();
s.pop();
int l = s.empty() ? -1 : s.top();
int r = len;
int width = (r - l) * (r - l - 1) / 2;
int lval = l == -1 ? 0 : mat[l];
int rval = r == len ? 0 : mat[r];
int height = mat[index] - max(lval, rval);
ans += width * height;
}
return ans;
}
int numSubmat(vector<vector<int>>& mat)
{
int n = mat.size(), m = mat[0].size();
vector<int> heights(m, 0);
int ans = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++) heights[j] = mat[i][j] == 0 ? 0 : heights[j] + 1;
ans += numMat(heights);
}
return ans;
}
标签:mat,int,max,heights,ans,单调,size
From: https://www.cnblogs.com/yaoguyuan/p/18637491