• 单调栈的四种用法


    单调栈主要用于解决 Next Greater Element 问题,即找左边/右边第一个比自己小/大的元素(位置)。

    以下是对四种问题的实现。

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
                    //   0  1  2  3  4  5
        vector<int> t = {4, 2, 3, 3, 5, 4};
        int n = (int)t.size();
        vector<vector<int>> a(4);
        for (int i = 0; i < 4; i++) {
            a[i] = t;
        }
    
        vector<vector<int>> ans(4, vector<int>(n, -1));
        vector<stack<int>> stk(4);
    
        // 找右边第一个比自己大的元素位置(0-index)
        // 输出应为 {4, 2, 4, 4, -1, -1},其中 -1 代表不存在
        // 栈自底向上单调递减(很容易从弹栈的条件看出来,栈顶需要大于等于带加入元素,因而是递减
        for (int i = 0; i < n; i++) {
            while (!stk[0].empty() && a[0][stk[0].top()] < a[0][i]) {
                ans[0][stk[0].top()] = i;
                stk[0].pop();
            }
            stk[0].push(i);
        }
    
        for (int i = 0; i < n; i++) {
            cout << ans[0][i] << " \n"[i == n - 1];
        }
    
        // 找右边第一个比自己小的元素位置(0-index)
        // 输出应为 {1, -1, -1, -1, 5, -1}
        // 栈自底向上单调递增
        for (int i = 0; i < n; i++) {
            while (!stk[1].empty() && a[1][stk[1].top()] > a[1][i]) {
                ans[1][stk[1].top()] = i;
                stk[1].pop();
            }
            stk[1].push(i);
        }
    
        for (int i = 0; i < n; i++) {
            cout << ans[1][i] << " \n"[i == n - 1];
        }
    
        // 找左边第一个比自己大的元素位置(0-index)
        // 输出应为 {-1, 0, 0, 0, -1, 4}
        // 栈自底向上严格单调递减
        for (int i = 0; i < n; i++) {
            while (!stk[2].empty() && a[2][stk[2].top()] <= a[2][i]) {
                stk[2].pop();
            }
            if (!stk[2].empty()) {
                ans[2][i] = stk[2].top();
            }
            stk[2].push(i);
        }
    
        for (int i = 0; i < n; i++) {
            cout << ans[2][i] << " \n"[i == n - 1];
        }
    
        // 找左边第一个比自己小的元素位置(0-index)
        // 输出应为 {-1, -1, 1, 1, 3, 3}
        // 栈自底向上严格单调递增
        for (int i = 0; i < n; i++) {
            while (!stk[3].empty() && a[3][stk[3].top()] >= a[3][i]) {
                stk[3].pop();
            }
            if (!stk[3].empty()) {
                ans[3][i] = stk[3].top();
            }
            stk[3].push(i);
        }
        
        for (int i = 0; i < n; i++) {
            cout << ans[3][i] << " \n"[i == n - 1];
        }
        return 0;
    }
    
  • 相关阅读:
    Python中常用的模块(sys模块)
    Python中常用的模块(OS模块)
    Python中常用的模块(time模块)
    Python中常用的模块(random模块)
    Python生成器详解
    Python装饰器详解
    python 两个list 求交集,并集,差集
    数据库中的视图索引
    数据库中的外键和主键理解
    mssql学习
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/15967981.html
Copyright © 2020-2023  润新知