155. 最小栈(java实现)--LeetCode

题目:

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

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

示例:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

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

提示:

  • pop、top 和 getMin 操作总是在 非空栈 上调用。

解法1:数组实现

/**
 * 思路:
 * 用数组实现stack
 * current指向的是还没有值的位置
 * push current下标不断移动。越界扩容
 * pop 出栈栈顶元素:current-1
 * top 获取栈顶元素:current-1
 * getMin 记录最小值,遍历整个数组
 */
    class MinStack {
    
    
        int[] arr;
        int current;
        /** initialize your data structure here. */
        public MinStack() {
    
    
            arr = new int[16];
            current=0;
        }

        public void push(int x) {
    
    
            if (current>=arr.length)grow();
            arr[current++]=x;
        }

        public void pop() {
    
    
            arr[--current]=0;
        }

        public int top() {
    
    
            return arr[current-1];
        }

        public int getMin() {
    
    
            int min=arr[0];
            for (int i=1;i<current;i++){
    
    
                if (arr[i]<min)min=arr[i];
            }
            return min;
        }
        private void grow() {
    
    
            int oldCapacity = arr.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            arr = Arrays.copyOf(arr, newCapacity);
        }
    }

在这里插入图片描述​​​​

解法2:链表实现

/**
 * 思路:
 * 用链表实现stack
 * 链表中记录min
 * push元素的时候,如果Node不存在,也就是第一个元素,最小值就他自己
 * 如果Node存在,新节点加入到链表头,指向链表。比较当前这个节点的值和min,在当前节点记录下当前状态的最小值
 * pop,当前的节点的下一个节点变成head,把当前节点赋值null,方便GC。(即使栈顶元素出栈,新的栈顶元素记录着当前状态的min值)
 * top直接返回head.value
 * getMin直接返回min
 */
    class MinStack {
    
    

        class Node{
    
    
            int value;
            Node next;
            int min;
            public Node(int value,int min){
    
    
                this.value=value;
                this.min=min;
            }
        }

        Node head;
        /** initialize your data structure here. */
        public MinStack() {
    
    

        }

        public void push(int x) {
    
    
            if (head==null){
    
    
                head=new Node(x,x);
            }else {
    
    
                Node new_node=new Node(x,Math.min(x,head.min));
                new_node.next=head;
                head=new_node;
            }
        }

        public void pop() {
    
    
            if (head!=null) {
    
    
                Node new_head = head.next;
                head = null;
                head = new_head;
            }
        }

        public int top() {
    
    
            if (head!=null)return head.value;
            return -1;
        }

        public int getMin() {
    
    
            if (head!=null)return head.min;
            return -1;
        }
    }

​​在这里插入图片描述

解法3:2个栈

/**
 * 思路:
 * 用2个栈实现stack
 * 一个正常的出入栈normal_stack,另外一个存放最小值min_stack
 * push如果min_stack栈顶元素大于等于当前值,把当前值存入
 * pop如果正常出栈的值和min_stack栈顶元素值一样,min_stack进行出栈操作
 */
class MinStack {
    
    
        ArrayDeque<Integer> normal_stack;
        ArrayDeque<Integer> min_stack;
        /** initialize your data structure here. */
        public MinStack() {
    
    
            normal_stack=new ArrayDeque<>();
            min_stack=new ArrayDeque<>();
        }
        public void push(int x) {
    
    
            if (normal_stack.isEmpty())min_stack.push(x);
            else {
    
    
                if (min_stack.peek()>=x)min_stack.push(x);
            }
            normal_stack.push(x);
        }

        public void pop() {
    
    
//            不自动拆箱
//            Integer pop = normal_stack.pop();
//            Integer min = min_stack.peek();

//            min.peek()获取的是地址值,不自动拆箱,没法和pop比较
//            if (pop==min.peek())min_stack.pop();
//            if (pop==min)min_stack.pop();
            int pop = normal_stack.pop();
            int min = min_stack.peek();
            if (pop==min)min_stack.pop();
        }

        public int top() {
    
    
            return normal_stack.peek();
        }

        public int getMin() {
    
    
            return min_stack.peek();
        }
    }

在这里插入图片描述

解法4:1个栈(栈中存放差值)

/**
 * 思路:
 * 用1个栈实现stack
 * 栈中存放peek=当前值x-min
 * 入栈的时候如果x是一个负数就更新min为v
 * 出栈的时候,如果是负数就用x(也就是现在的min)-v求出上一个min的值
 * top的时候需要注意:如果栈中元素小于0(最小值),返回min。否则返回peek+min
 * 
 * 注意:为了防止超出int的范围我们这里最后都设置成long
 */
 	class MinStack {
    
    
        ArrayDeque<Long> stack;
        long min;
        /** initialize your data structure here. */
        public MinStack() {
    
    
            stack=new ArrayDeque<>();
        }

        public void push(int x) {
    
    
            if (stack.isEmpty()){
    
    
                min=x;
                stack.push(0L);
            }else {
    
    
                long peek = x - min;
                stack.push(peek);
                if (peek<0)min=x;
            }

        }

        public void pop() {
    
    
            if (stack.isEmpty()) return;
            if (stack.peek()<0)min=min-stack.pop();
            else stack.pop();
        }

        public int top() {
    
    
            Long peek = stack.peek();
            if (peek<0)return (int) min;
            else return (int) (peek+min);
        }

        public int getMin() {
    
    
            return (int)min;
        }
    }

在这里插入图片描述

解法5:1个栈(当前值是最小值时存放2次)

/**
 * 思路:
 * 栈中记录2个最小值
 * 入栈:如果入栈的当前值小于最小值min,先把min在入栈一次,之后更新min,之后在入栈当前值入栈。这样即使当前值出栈也可以找到之前的最小值min
 * 出栈:如果出栈的是最小值,就需要更新最小值:在进行一次出栈,更新min
 */
    class MinStack {
    
    
        ArrayDeque<Integer> stack;
        int min;
        /** initialize your data structure here. */
        public MinStack() {
    
    
            stack=new ArrayDeque<>();
        }

        public void push(int x) {
    
    
            if (stack.isEmpty()||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;
        }
    }

在这里插入图片描述

解法6:1个栈(存放2个值,栈顶是最小值)

/**
 * 思路:
 * 入栈:先记录栈顶元素(之前的最小值)。再存放当前值,之后比较当前值和最小值,存放当前的最小值
 * 出栈:出2次
 * top:先出栈当前最小值,记录下来。之后获取栈顶元素,就是当前值。之后恢复栈(入栈最小值)
 * getMin:栈顶元素就是最小值
 */
class MinStack {
    
    
        ArrayDeque<Integer> stack;
        /** initialize your data structure here. */
        public MinStack() {
    
    
            stack=new ArrayDeque<>();
        }

        public void push(int x) {
    
    
            stack.push(x);
            if (stack.isEmpty()){
    
    
                stack.push(x);
            }else {
    
    
                Integer min = stack.peek();
                stack.push(min>x?x:min);
            }
        }

        public void pop() {
    
    
            stack.pop();
            stack.pop();
        }

        public int top() {
    
    
            Integer pop = stack.pop();
            Integer peek = stack.peek();
            stack.push(pop);
            return peek;
        }

        public int getMin() {
    
    
            return stack.peek();
        }
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38783664/article/details/110502461