✿-9例题 栈、辅助栈--最小栈-155

Posted on 2020-11-07 21:35  MissRong  阅读(90)  评论(0)    收藏  举报

✿-9例题 栈、辅助栈--最小栈-155

一、题目

 

 

 

 

 

 二、Java实现代码

1.第一种解法--单个栈(国际站最高票):

package shuJuJieGou.ZhanAndHash;

import java.util.Stack;

/**
 * @Author : ASUS and xinrong
 * @Version : 2020/11/7 & 1.0
 * 栈、辅助栈
 * 最小栈—155
 * 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 *
 * push(x) —— 将元素 x 推入栈中。
 * pop() —— 删除栈顶的元素。
 * top() —— 获取栈顶元素。
 * getMin() —— 检索栈中的最小元素。
 * 注意:pop、top 和 getMin 操作总是在 非空栈 上调用。
 *
 * 思路:
 * 1)审题:随时取出当前栈内的最小值
 * 2)存在的问题:在对栈进行不断地操作中,栈内元素不好控制
 * 3)解决办法:
 * (1)一个栈 (国际站最高票):    用一个自定义的变量来存当前栈内的最小值 √
 * (2)增加辅助栈
 *
 * 复杂度分析:
 * 时间复杂度:O(1),“出栈”、“入栈”、“查看栈顶元素”的操作不论数据规模多大,
 * 都只是有限个步骤,因此时间复杂度是:O(1)。
 * 空间复杂度:O(N),这里 N 是读出的数据的个数。
 */
public class MinStack {
    int min = Integer.MAX_VALUE;
    private Stack<Integer> stack;
    public MinStack() {
        stack = new Stack<>();
    }
    public void push(int x) {
        //有等于号是因为,如果后来新入栈的元素等于当前的min(之前入栈的元素),
        // 它一样会被列为新的min---入两次栈,这样在后面出栈(出两次栈)的情况下才不会错
        if (x <= min) {
            //原来的min再一次入栈是为了在最小元素(栈顶元素)出栈之后,它继承最小元素min
            stack.push(min);
            min = x;
        }
        stack.push(x);
    }
    public void pop() {
        //如果当前出栈的是最小元素
        if (stack.pop() == min) {
            //最小元素就更新为下一个出栈的元素
            //多的这次出栈是因为 push的时候多了一步将原来min再次入栈的操作
            min = stack.pop();
        }
    }
    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return min;
    }
    public static void main(String[] args) {
        MinStack minStack = new MinStack();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        int min1 = minStack.getMin();
        System.out.println("当前最小值:"+min1);
        System.out.println("栈顶元素出栈");
        minStack.pop();
        int top = minStack.top();
        System.out.println("当前栈顶元素:"+top);
        int min2 = minStack.getMin();
        System.out.println("当前最小值:"+min2);
    }
}

2.第二种解法--栈、辅助栈

1)两个栈同步

package shuJuJieGou.ZhanAndHash;

import java.util.Stack;

/**
 * @Author : ASUS and xinrong
 * @Version : 2020/11/7 & 1.0
 * 栈、辅助栈
 * 最小栈—155
 * 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 *
 * push(x) —— 将元素 x 推入栈中。
 * pop() —— 删除栈顶的元素。
 * top() —— 获取栈顶元素。
 * getMin() —— 检索栈中的最小元素。
 * 注意:pop、top 和 getMin 操作总是在 非空栈 上调用。
 *
 * 思路:
 * 1)审题:随时取出当前栈内的最小值
 * 2)存在的问题:在对栈进行不断地操作中,栈内元素不好控制
 * 3)解决办法:
 * (1)一个栈
 * (2)增加辅助栈:
 *      两个栈一直同步   一起增加或删除一个元素可以保证两个栈的元素数量一直相同 √
 *      两个栈不一直同步
 *
 * 复杂度分析:
 * 时间复杂度:O(1),“出栈”、“入栈”、“查看栈顶元素”的操作不论数据规模多大,
 *             都只是有限个步骤,因此时间复杂度是:O(1)。
 * 空间复杂度:O(N),这里 N 是读出的数据的个数。
 */
public class MinStack_Helper_Together {
    /**数据栈*/
    private Stack<Integer> data;
    /**辅助栈*/
    private Stack<Integer> helper;
    public MinStack_Helper_Together() {
        data = new Stack<>();
        helper = new Stack<>();
    }
    /**
     * 增加元素
     * @param x
     */
    public void push(int x) {
        //数据栈增加元素
        data.add(x);
        //辅助栈也增加元素
        if (helper.isEmpty() || helper.peek() >= x) {
            helper.add(x);
        } else {
            helper.add(helper.peek());
        }
    }
    /**
     * 出栈
     */
    public void pop() {
        if (!data.isEmpty()) {
            helper.pop();
            data.pop();
        }
    }
    /**
     * 读取栈顶元素
     * @return
     */
    public int top() {
        if (!data.isEmpty()) {
            return data.peek();
        }
        throw new RuntimeException("栈中元素为空,此操作非法!");
    }
    /**
     * 取出当前栈中最小的元素
     * @return
     */
    public int getMin() {
        if (!helper.isEmpty()) {
            return helper.peek();
        }
        throw new RuntimeException("栈中元素为空,此操作非法!");
    }
    public static void main(String[] args) {
        MinStack_Helper_Together minStack = new MinStack_Helper_Together();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        int min1 = minStack.getMin();
        System.out.println("当前最小值:"+min1);
        System.out.println("栈顶元素出栈");
        minStack.pop();
        int top = minStack.top();
        System.out.println("当前栈顶元素:"+top);
        int min2 = minStack.getMin();
        System.out.println("当前最小值:"+min2);
    }
}

2)两个栈不同步

package shuJuJieGou.ZhanAndHash;

import java.util.Stack;

/**
 * @Author : ASUS and xinrong
 * @Version : 2020/11/7 & 1.0
 * 栈、辅助栈
 * 最小栈—155
 * 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 * push(x) —— 将元素 x 推入栈中。
 * pop() —— 删除栈顶的元素。
 * top() —— 获取栈顶元素。
 * getMin() —— 检索栈中的最小元素。
 * 注意:pop、top 和 getMin 操作总是在 非空栈 上调用。
 *
 * 思路:
 * 1)审题:随时取出当前栈内的最小值
 * 2)存在的问题:在对栈进行不断地操作中,栈内元素不好控制
 * 3)解决办法:
 * (1)一个栈
 * (2)增加辅助栈:
 * 两个栈一直同步
 * 两个栈不一直同步  出栈同步即可 √
 *
 * 复杂度分析:
 * 时间复杂度:O(1),“出栈”、“入栈”、“查看栈顶元素”的操作不论数据规模多大,
 * 都只是有限个步骤,因此时间复杂度是:O(1)。
 * 空间复杂度:O(N),这里 N 是读出的数据的个数。
 */
public class MinStack_Helper {
    /**数据栈*/
    private Stack<Integer> data;
    /**辅助栈*/
    private Stack<Integer> helper;

    public MinStack_Helper() {
        data = new Stack<>();
        helper = new Stack<>();
    }
    /**
     * 入栈
     * @param x
     */
    public void push(int x) {
        data.add(x);
        //辅助栈在必要的情况下才添加
        if (helper.isEmpty() || helper.peek() >= x) {
            helper.add(x);
        }
    }
    /**
     * 出栈
     */
    public void pop() {
        if (!data.isEmpty()) {
            // 注意:声明成 int 类型,这里完成了自动拆箱,从 Integer 转成了 int,因此下面的比较可以使用 "==" 运算符
            // 如果把 top 变量声明成 Integer 类型,下面的比较就得使用 equals 方法
            int pop = data.pop();
            //辅助栈的栈顶元素等于刚刚出去的元素,那它也出栈
            if (pop == helper.peek()) {
                helper.pop();
            }
        }
    }
    /**
     *获取栈顶元素
     * @return
     */
    public int top() {
        if (!data.isEmpty()) {
            return data.peek();
        }
        throw new RuntimeException("栈内元素为空,此操作非法!");
    }
    /**
     * 获取当前栈的最小元素
     * @return
     */
    public int getMin() {
        if (!helper.isEmpty()) {
            return helper.peek();
        }
        throw new RuntimeException("栈内元素为空,此操作非法!");
    }

    public static void main(String[] args) {
        MinStack_Helper minStack = new MinStack_Helper();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        int min1 = minStack.getMin();
        System.out.println("当前最小值:"+min1);
        System.out.println("栈顶元素出栈");
        minStack.pop();
        int top = minStack.top();
        System.out.println("当前栈顶元素:"+top);
        int min2 = minStack.getMin();
        System.out.println("当前最小值:"+min2);
    }
}

 

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3