首页 > 其他分享 >单调栈

单调栈

时间:2024-12-28 14:41:27浏览次数:4  
标签:mat int max heights ans 单调 size

[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

相关文章

  • JVM内存模型、垃圾回收机制及简单调优方式
    JVM内存模型:1.方法区  用来存放类加载的信息,同时存放静态属性和方法(静态方法和普通方法)  jdk1.7之后,取消了方法区名称,改为元空间、方法区也叫元空间也叫永久区  方法区中的数据,可以被多线程共享。访问时会有数据共享的安全问题2.堆区  用来存放对象或数......
  • 【多维DP】【准NOI难度】力扣3251. 单调数组对的数目 II
    给你一个长度为n的正整数数组nums。如果两个非负整数数组(arr1,arr2)满足以下条件,我们称它们是单调数组对:两个数组的长度都是n。arr1是单调非递减的,换句话说arr1[0]<=arr1[1]<=…<=arr1[n-1]。arr2是单调非递增的,换句话说arr2[0]>=ar......
  • Luogu P8112 [Cnoi2021] 符文破译 题解 [ 蓝 ] [ KMP ] [ 线性 dp ] [ 决策单调性 dp
    符文破译:KMP+dp的好题。暴力dp不难打出一个暴力dp:设计\(dp_i\)表示当前前\(i\)位全部完成了匹配,所需的最小分割数。转移也是简单的,我们在KMP的过程中进行dp转移,每次选取next不断跳向再前面的next,然后进行转移即可。很显然一个字符集大小为\(1\)的串就能轻松......
  • harmony_flutter_微信支付的简单调用
    harmony_flutter_微信支付的简单调用一.配置鸿蒙应用信息参考文档:https://pay.weixin.qq.com/doc/v3/merchant/4012073588#%E9%B8%BF%E8%92%99-SDK-%E8%B0%83%E7%94%A8%E8%AF%B4%E6%98%8E关于「鸿蒙应用」中的BundleID、Identifier、以及应用下载地址的提供的说明如下:1.Bu......
  • idea简单调试
    1.行断点是一个小红原点然后,在main方法中点击调试,程序运行时会在该点停顿,点击恢复程序就会继续运行2.详细断点|源断点shift+左键唤出断点是一个小黄圆点,并且有一些信息若点击挂起再点完成,将会变为小红圆点点击调试,控制台给出断点位置3.方法断点是一个小方块,会在......
  • 【决策单调性】P3648 [APIO2014] 序列分割 题解
    题目链接:P3648[APIO2014]序列分割(注:由于本题解的状态转移方程需要用到\(k\),所以原题中的\(k\)对应本题解中的\(m\)。)给你一个长度为\(n\)的序列\(A_1,A_2,...,A_n\),一开始把它看作一个块。初始你的分数为\(0\),现在你需要进行下列操作恰好\(m\)次:选一个块,并从一处......
  • 【LeetCode: 402. 移掉 K 位数字 + 单调栈】
    ......
  • 单调栈 学习与启发思路
    本文帮助明确单调栈所需判断重点并进行分析便于快速找到切入点总结:在了解单调栈之后,能快速得出while循环条件的能力是关键前提:B站灵茶山艾府单调栈细讲注1:请观看该视频后或了解单调栈之后->阅读该文章注2:以下讲解均为从右向左遍历从左向右暂请自行理解运用引入......
  • LeetCode【代码随想录】刷题(单调栈篇)
    739.每日温度力扣题目链接题目:给定一个整数数组temperatures,表示每天的温度,返回一个数组answer,其中answer[i]是指对于第i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0来代替。思路:维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列......
  • 决策单调性优化dp学习笔记
    点的第一个省选级算法,算是一个很好的过渡。决策单调性,也称四边形不等式优化dp。主要适用于转移式子大概长这样的时候:\(f_i=\min/\max\{f_j+w(j,i)\}\),其中\(w(j,i)\)满足四边形不等式。四边形不等式当\(a\leb\lec\led\)时,若存在$w(a,c)+w(b,d)\lew(a,d)+w(b,c)......