zoukankan      html  css  js  c++  java
  • 3.(155)最小栈

    2020年3月21日

    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.
    

    设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

    • push(x) -- 将元素 x 推入栈中。
    • pop() -- 删除栈顶的元素。
    • top() -- 获取栈顶元素。
    • getMin() -- 检索栈中的最小元素。

    示例:

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

    方法1

    最直接的方法是用两个栈,一个保存正常的入栈出栈的值,另一个栈去存最小值,也就是用当前栈顶保存当前所有元素的最小值,流程如下:

    1. 将第一个元素入栈
    2. 新加入的元素如果大于栈顶元素,那么新加入的元素就不处理
    3. 新加入元素如果小于等于栈顶元素,那么新元素入栈
    4. 出栈元素不等于栈顶元素,不操作
    5. 出栈元素等于栈顶元素,将栈顶元素出栈
    class MinStack{
        private Stack<Integer> stack;
        private Stack<Integer> minStack;
        
        public MinStack(){
            stack=new Stack<>();
            minStack=new Stack<>();
        }
        
        public void push(int x){
            stack.push(x);
            if(!minStack.isEmpty()){
                int top=minStack.peek();
                //小于等于的时候才入栈
                if(x<=top){
                	minStack.push(x);
                }
            }else{
                minStack.push(x);
            }
        }
        
        public void pop(){
            int pop=stack.pop();
            
            int top=minStack.peek();
            //等于的时候再出栈
            if(pop==top){
                minStack.pop();
            }
        }
        
        public int top(){
            return stack.peek();
        }
        
        public int getMin(){
            return minStack.peek();
        }
        
        public int getMin(){
            return minStack.peek();
        }
    }
    

    方法2

    方法1中使用了两个栈实现,那么现在尝试用一个栈实现,只用一个变量去保存最小值,如果新压入的值更小,那么在压入新元素前将原来的min压入栈中,并更新最小值

    class minStack{
        int min = Integer.MIN_VALUE;
        Stack<Integer> stack = new Stack<Integer>();
        public void push(int x){
            if(x<=min){
                stack.push(min);
                min=x;
            }
            stack.push(x);
        }
        
        public void pop(){
            if(stack.pop()==min){
                min = stack.pop();
            }
        }
        
        public int top(){
            return stack.peek();
        }
        
        public int getMin(){
            return min;
        }
    }
    

    方法3

    从方法2中可以看出,关键要解决的问题是当有新的更小值的时候,之前的最小值怎么办?

    方法3用另一种思路,通过min存储当前最小值,栈中存储入栈的值与最小值的差值

    public class MinStack{
        long min;
        Stack<long> stack;
        
        public MinStack(){
            stack=new Stack<>();
        }
        
        public void push(int x){
            if(stack.isEmpty()){
                min=x;
                stack.push(x-min);
            }else{
                stack.push(x-min);
                if(x<min){
                    min=x;
                }
            }
        }
        
        public void pop(){
            if(stack.isEmpty()) return;
            long pop = stack.pop();
            if(pop<0){
                min=min-pop;
            }
        }
        
        public int top(){
            long top=stack.peek();
            if(top<0){
                return (int)(min);
            }else{
                return (int)(top+min);
            }
        }
        
        
        public int getMin(){
            return (int) min;
        }
    }
    

    上述解法的一个缺点是保存的是差值,所以可能造成溢出,所以用了范围更大的long类型,这个解法在最小值更新时不需要把之前的最小值存起来,会节省一些空间

    方法4

    不用java提供的stack,在Node结点中增加min字段

    class MinStack{
        class Node{
            int value;
            int min;
            Node next;
            
            Node(int x,int min){
                this.value=x;
                this.min=min;
                next=null;
            }
        }
        Node head;
        
        public void push(int x){
            if(null==head){
                head=new Node(x,x);
            }else{
                Node n = new Node(x,Math.min(x,head.min))
                n.next=head;
                head=n;
            }
        }
        
        public void pop(){
            if(head!=null)
                head=head.next;
        }
        
        public int top(){
            if(head!=null)
                return head.value;
            return -1;
        }
        
        public int getMin(){
            if(head!=null)
                return head.min;
            return -1;
        }
    }
    
  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/ningdeblog/p/12542013.html
Copyright © 2011-2022 走看看