zoukankan      html  css  js  c++  java
  • [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;
    };
    
  • 相关阅读:
    iOS image.size大小实际输出的值跟图片像素的关系
    iOS 记录蓝牙传输相关进制转换/字节转换/NSData转换/大小端转换
    Objective-C 中Socket常用转换机制(NSData,NSString,int,Uint8,Uint16,Uint32,byte[])
    ios-如何将UIColor RGB颜色转换为uint32_t值
    iOS 多国语言判断
    android 通过WIFI调试和adb指令推送文件到安卓设备
    iOS ViewController跳转界面的几种方法简单总结
    整理汇总能够提升文字工作效率的工具app分享给大家
    js 把字符串转换成数组,数组去重后再转成字符串
    我和朋友写的《Go语言从基础到中台微服务实战开发》已出版在京东,当当上可以购买了
  • 原文地址:https://www.cnblogs.com/arcsinw/p/11276835.html
Copyright © 2011-2022 走看看