• [LeetCode] 155. Min Stack


    Description

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

    • push(x) -- Push element x onto stack.
    • pop() -- Removes the element on top of the stack.
    • top() -- Get the top element.
    • getMin() -- Retrieve the minimum element in the stack.

    Example:

    MinStack minStack = new MinStack();
    minStack.push(-2);
    minStack.push(0);
    minStack.push(-3);
    minStack.getMin();   --> Returns -3.
    minStack.pop();
    minStack.top();      --> Returns 0.
    minStack.getMin();   --> Returns -2.
    

    Analyse

    设计一个支持以O(1)时间复杂度获取当前最小值的栈

    第一种思路,使用两个栈,一个存数据,一个存当前最小值,这种方法写起来简单,但需要两个栈

    data    min
    3       3
    2       2
    1       1
    4       1
    1       1
    
    class MinStack {
    public:
        stack<int> data;
        stack<int> min;
    
        MinStack() {    }
    
        void push(int x) {
            data.push(x);
            if (min.empty() || (x <= min.top()))
            {
                min.push(x);
            }
            else
            {
                min.push(min.top());
            }
        }
    
        void pop() {
            data.pop();
            min.pop();
        }
    
        int top() {
            return data.top();
        }
    
        int getMin() {
            return min.top();
        }
    };
    

    以上的方法中最小值可能被重复存多次,造成内存的浪费,可以继续改进

    data    min
    3       3
    2       2
    1       1
    4
    1       1
    

    修改MinStackpushpop,减少minimal中的重复元素

    class MinStack {
    public:
        stack<int> data;
        stack<int> minimal;
    
        MinStack() {    }
    
        void push(int x) {
            data.push(x);
    
            if (minimal.empty() || minimal.top() >= x)
            {
                minimal.push(x);
            }
        }
    
        void pop() {
            if (!minimal.empty() && data.top() == minimal.top())
            {
                minimal.pop();
            }
    
            data.pop();
        }
    
        int top() {
            return data.top();
        }
    
        int getMin() {
            return minimal.top();
        }
    };
    

    第二种思路,使用一种数据结构同时存数据和最小值,只使用一个栈

    class Item{
        int val;
        int min;
    }
    
    class MinStack {
    public:
        class Item {
            public:
                Item(int v, int m): val(v), min(m) {}
                int val;
                int min;
        };
    
        stack<Item> data;
    
        MinStack() { }
    
        void push(int x) {
            data.push(Item(x, data.empty() ? x : min(x, data.top().min)));
        }
    
        void pop() {
            data.pop();
        }
    
        int top() {
            return data.top().val;
        }
    
        int getMin() {
            return data.top().min;
        }
    };
    

    第三种思路,使用一个栈,val和min都存在这个栈中,通过某种方式区分(来自leetcode)
    如果当前push的值xmin_val小,将之前的min_val压栈,再将x压栈

    pop的时候先取出真正的数据t

    这个数据等于min_val时,再top + pop一次,更新min_val

    这个数据不等于min_val时,MinStack中没有push之前的min_val,无需进行操作

    data    MinStack    min_val
                        INT_MAX
    3       INT_MAX     3           min_val
            3                       data
    
    2       3           2           min_val
            2                       data
    
    1       2           1           min_val
            1                       data
    
    4       4           1           data
    
    1       1           1           min_val
            1                       data
    
    class MinStack {
    public:
        MinStack() {
            ios::sync_with_stdio(false);
            std::cin.tie(nullptr);
            std::cout.tie(nullptr);
    
            min_val = INT_MAX;
        }
    
        void push(int x) {
            if (x <= min_val){
                data.push(min_val);
                min_val = x;
            }
            data.push(x);
        }
    
        void pop() {
            int t = data.top();
            data.pop();
            if (t == min_val){
                min_val = data.top();
                data.pop();
            }
        }
    
        int top() {
            return data.top();
        }
    
        int getMin() {
            return min_val;
        }
    private:
        int min_val;
        stack<int> data;
    };
    
  • 相关阅读:
    【Java】IO流--文件夹的复制
    【Java】IO流--序列化与反序列化
    【Java】Java中的数组是对象吗?(转载)
    【Java】Java漫谈-数组(转载)
    【Java】IO流--对象流--ObjectInputStream、ObjectOutputStream
    【Java】IO流--数据流--DataInputStream、DataOutputStream
    【Java】IO流--打印流--PrintStream
    【Java】IO流--转换流--InpuStreamReader、OutputStreamWriter
    CentOS快速安装Nginx的方法,nginx如何启动重启停止
    Mac查看端口号是否被占用及释放
  • 原文地址:https://www.cnblogs.com/arcsinw/p/11276835.html
Copyright © 2020-2023  润新知