Data Structures and Algorithms 5-2. Monotone-Stack (1/1)

Monotone-Stack

1. Implementation

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

void output(vector<int>& arr) {
    for (auto x : arr) printf("%5d", x);
    printf("\n");
}

int main() {
    int n;
    cin >> n;
    vector<int> ind(n), arr(n), pre(n), next(n);
    stack<int> s;
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
        ind[i] = i;
    }
    for (int i = 0; i < n; i++) {
        while (s.size() && arr[i] < arr[s.top()]) {
            next[s.top()] = i;
            s.pop();
        }
        if (s.size() == 0) pre[i] = -1;
        else pre[i] = s.top();
        s.push(i);
    }
    while (s.size()) {
        next[s.top()] = n;
        s.pop();
    }
    output(ind);
    output(arr);
    output(pre);
    output(next);

    return 0;
}

2. Leetcode

Leetcode- 155, 503, 901, 739, 84, 1856, 907, 496, 456, 42

155

class MinStack {
public:
    stack<int> s, min_s;
    MinStack() {

    }

    void push(int val) {
        s.push(val);
        if (min_s.size() == 0 || min_s.top() >= val) min_s.push(val);
        return ;
    }

    void pop() {
        int temp = s.top();
        s.pop();
        if (temp == min_s.top())  min_s.pop();
        return ;
    }

    int top() {
        return s.top();
    }

    int getMin() {
        return min_s.top();
    }
};

503

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> new_nums, next(2 * nums.size(), -1), ans;
        stack<int> s;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < nums.size(); j++) new_nums.push_back(nums[j]);
        }
        for (int i = 0; i < new_nums.size(); i++) {
            while (s.size() && new_nums[i] > new_nums[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            s.push(i);
        }
        for (int i = 0; i < nums.size(); i++) {
            if (next[i] == -1) ans.push_back(-1);
            else ans.push_back(new_nums[next[i]]);
        }
        return ans;
    }
};

901

class StockSpanner {
public:
    stack<int> s;
    vector<int> data;
    int cnt;
    StockSpanner() : cnt(0) {}

    int next(int price) {
        while (s.size() && price >= data[s.top()]) s.pop();
        int ans = cnt - (s.size() ? s.top() : -1);
        s.push(cnt);
        data.push_back(price);
        cnt++;
        return ans;
    }
};

739

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int n = temperatures.size();
        vector<int> next(n), ans(n);
        stack<int> s;
        for (int i = 0; i < n; i++) {
            next[i] = i;
            while (s.size() && temperatures[i] > temperatures[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            s.push(i);
        }
        for (int i = 0; i < n; i++) {
            ans[i] = next[i] - i;
        }
        return ans;
    }
};

84

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> s;
        int n = heights.size(), ans = 0;
        vector<int> pre(n, -1), next(n, n);
        for (int i = 0; i < n; i++) {
            while (s.size() && heights[i] <= heights[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            if (s.size()) pre[i] = s.top();
            s.push(i);
        }
        for (int i = 0; i < n; i++) {
            ans = max(ans, heights[i] * (next[i] - pre[i] - 1));
        }
        return ans;
    }
};

1856

class Solution {
public:
    int maxSumMinProduct(vector<int>& nums) {
        long long ans = 0, temp;
        int n = nums.size(), mod_num = 1e9 + 7;
        stack<long long> s;
        vector<long long> pre_nums(n + 1, 0), prev(n, -1), next(n, n);
        for (int i = 1; i <= n; i++) pre_nums[i] = pre_nums[i - 1] + nums[i - 1];
        for (int i = 0; i < n ; i++) {
            while (s.size() && nums[i] < nums[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            if (s.size()) prev[i] = s.top();
            s.push(i);
        }
        for (int i = 0; i < n; i++) {
            temp = nums[i] * (pre_nums[next[i]] - pre_nums[prev[i] + 1]);
            ans = max(ans, temp);
        }
        return ans % mod_num;
    }
};

907

class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        stack<int> s;
        int n = arr.size(), mode_num = 1e9 + 7;
        long long ans = 0;
        vector<int> pre(n, -1), next(n, n);
        for (int i = 0; i < n; i++) {
            while (s.size() && arr[i] < arr[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            if (s.size()) pre[i] = s.top();
            s.push(i);
        }
        for (int i = 0; i < n; i++) {
            ans += (long long)arr[i] * (i - pre[i]) * (next[i] - i);
            ans %= mode_num;
        }
        return ans % mode_num;
    }
};

496

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n = nums2.size(), m = nums1.size();
        vector<int> ans(m), next(10005, -1);
        stack<int> s;
        for (int i = 0; i < n; i++) {
            while (s.size() && nums2[i] > s.top()) {
                next[s.top()] = nums2[i];
                s.pop();
            }
            s.push(nums2[i]);
        }
        for (int i = 0; i < m; i++) {
            ans[i] = next[nums1[i]];
        }
        return ans;
    }
};

456

class Solution {
public:
    bool find132pattern(vector<int>& nums) {
        int n = nums.size();
        vector<int> prev(n, -1), next(n, n);
        deque<int> q;
        stack<int> s;
        for (int i = 0; i < n; i++) {
            while (q.size() && nums[i] <= nums[q.back()]) q.pop_back();
            if (q.size()) prev[i] = q.front();
            q.push_back(i);
        }
        for (int i = 0; i < n; i++) {
            while (s.size() && nums[i] >= nums[s.top()]) {
                next[s.top()] = i;
                s.pop();
            }
            s.push(i);
        }
        for (int i = 0; i < n; i++) {
            int ind = next[i];
            q.clear();
            for (int j = i + 1; j < ind; j++) {
                while (q.size() && nums[j] > nums[q.back()]) q.pop_back();
                q.push_back(j);
            }
            if (prev[i] != -1 && q.size() && nums[q.front()] > nums[prev[i]]) return true;
        }
        return false;
    }
};

42

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(), ans = 0, base, a, b;
        stack<int> s;
        for (int i = 0; i < n; i++) {
            while (s.size() && height[i] > height[s.top()]) {
                base = s.top();
                s.pop();
                if (s.size() == 0) continue;
                a = height[i] - height[base];
                b = height[s.top()] - height[base];
                ans += (i - s.top() - 1) * min(a, b);
            }
            s.push(i);
        }
        return ans;
    }
};
Yingzhe Dong
Yingzhe Dong
Graduate Student of Computer Science

I am a full-stack developer with interests in software development, system architecture, and distributed system.