思路:

一开始只是简单的模拟有min的栈,最直白的就是用一个指针或者变量维持最小值,每次插入删除都更新一次,在调用min的时候就是O(1),但是这个就是每次都要sort的复杂度(不是find,找不到对比的对象,这里小混),基础的就是这么做了。
看了别人的发现是滑动窗口,只不过活动窗口的时候,当前最值的左区是先失效的,所以每一次的最值都不用考虑左界左的情况只需取代他们,最值右区是候选最值,即使不是当前最值也可能在在他左边的旧最值消失后成为新的最值。这道题是反的,每次top走到一个新值和旧的最值对比,旧最值的左边是有可能成为新最值的(统辖新最值的左边),旧最值的右肯定比旧最值先消失,先消失的一端对于没法更新的值可以直接取代,反正他们会先死,没死的时候旧最值也不会死,所以一定轮不到他们,有更新的则成为新最值。

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
//23:00--0:36
class Solution {
public:
    void push(int value) {
        stack.push_back(value);
        heap.push_back(value);
        make_heap(heap.begin(), heap.end(), greater<int>());
    }
    void pop() {
        int m = stack.back();
        stack.pop_back();
        auto it = find(heap.begin(), heap.end(), m);
        heap.erase(it);
        make_heap(heap.begin(), heap.end(), greater<int>());
    }
    int top() {
        return stack.back();
    }
    int min() {
        return heap.front();
    }
private:
    vector<int> stack, heap;
};
class Solution2{
public:
    void push(int value) {
        stack.push_back(value);
        //等于也要入栈,如果等于不保存,待会出的时候等于会被出掉(相当于每个元素的是单独的与minStack一一对应的),则丢失min
        if(minStack.empty() || minStack.back() >= value){
            minStack.push_back(value);
        }
    }
    void pop() {
        //只会是等于的时候要pop 维持的minStack,大于不用更新minStack,不可能小于,不然他就会是minStack的最小元素即等于的情况
        if(stack.back() == minStack.back()){
            minStack.pop_back();
        }
        stack.pop_back();
    }
    int top() {
        return stack.back();
    }
    int min() {
        return minStack.back();
    }
private:
    vector<int> stack, minStack;
};


int main() {
    Solution s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(1);
    cout<<s.top()<<s.min();
    s.pop();
    s.pop();
    cout<<s.top();
    cout<<s.min();


    return 0;
}