Java 如何实现可以获取最小值的栈?

版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/82878480

方法一、最基础得方式?

1.用一个变量保存最小值,在push的时候更新这个最小值

2.但是只能进不能出,出来的话就得重新遍历栈中得数据然后重新计算

3.时间O(1) ,空间O(1)


## 方法二、如何实现时间最短?
1.以空间换时间,即再申请一个辅组栈,辅助栈中只保留最小值
2. 时间O(1) 空间(n)
3. 代码实现
package shuju;

import java.util.ArrayList;
import java.util.List;

public class MinStack {

    private List<Integer> data = new ArrayList<Integer>(); //数据栈
    private List<Integer> min = new ArrayList<Integer>();  //存放最小值得栈

    public void push(int num) {
        data.add(num);
        if (min.size() == 0) {
            //如果最小栈空,则初始化
            min.add(num);
        } else {

            if (num >= getMin()) {
                //这里不要写 num >= min.get(min.size() -1);会有size等于0的情况,而且本身定义好了getMin()方法,无需多写
                //如果push的值大于等于data栈中的值,push上一个min栈最后一个数据
                min.add(min.get(min.size() - 1));
            } else {
                min.add(num);
            }
        }


    }

    public int pop() {
        if (data.size() == 0) {
            return -1;
        }
        //因为Min和data栈的大小都是一样的,所以无需判断min栈是否为空
        min.remove(min.size() - 1);
        //返回的是data栈移除的数据
        return data.remove(data.size() - 1);
    }


    public int getMin() {
        if (data.size() == 0) {
            return -1;
        } else {
            return min.get(min.size() - 1);
        }
    }


    public static void main(String[] args) {
        MinStack minStack = new MinStack();
        minStack.push(14);
        minStack.push(2);
        minStack.push(3);
        minStack.push(4);
        minStack.push(5);
        System.out.println(minStack.getMin());

        minStack.pop();
        System.out.println(minStack.getMin());
        minStack.push(1);
        System.out.println(minStack.getMin());
    }


}


4.输出结果: 2 2 1

方法三、异常处理方法二

1.因为方法二如果push的是-1 或者其它值会有错误,所以用Java异常处理

2.具体做法

将代码中的  return -1变成下面的
 throw new EmptyStackException();

方法四、基于方法三代码优化

1.如果入栈分别是2、1、2、3、4、5、6,辅助栈里面会变成 2、1、1、1、1、1、1,有大量重复数据

2.这个时候引入索引

3.具体做法是

##### 		A.当新入的数据不比min最后一个小的时候,不入min栈
##### 		B.当pop()的时候判断data的size()和min栈栈顶的索引是否一致,
##### 	    C:一致的话min  data都pop()   返回的是min()栈顶元素
##### 	    D:不一致只对data 栈pop()     返回的还是min()栈顶元素

4. 代码实现

package shuju;

import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.List;

public class MinStack {

    private List<Integer> data = new ArrayList<Integer>(); //数据栈
    private List<Integer> min = new ArrayList<Integer>();  //存放最小值得栈

    public void push(int num) {
        data.add(num);
        if (min.size() == 0) {
            //如果最小栈空,则初始化
            min.add(num);
        } else {

            if (num >= getMin()) {
                //这里不要写 num >= min.get(min.size() -1);会有size等于0的情况,而且本身定义好了getMin()方法,无需多写
                //如果push的值大于等于data栈中的值,push上一个min栈最后一个数据
//                min.add(min.get(min.size() - 1));
            } else {
                min.add(num);
            }
        }


    }

    public int pop() {
        if (data.size() == 0) {
            throw new EmptyStackException();
        }
        //因为Min和data栈的大小都是一样的,所以无需判断min栈是否为空

        if (data.size() > min.size()) {
            //说明data的元素多,min栈数据不能移除
        } else {
            min.remove(min.size() - 1);
        }

        //返回的是data栈移除的数据
        return data.remove(data.size() - 1);
    }


    public int getMin() {
        if (data.size() == 0) {
            throw new EmptyStackException();
        } else {
            return min.get(min.size() - 1);
        }
    }


    public static void main(String[] args) {
        MinStack minStack = new MinStack();
        minStack.push(14);
        minStack.push(2);
        minStack.push(2);
        minStack.push(2);
        minStack.push(2);
        System.out.println(minStack.getMin());

        minStack.pop();
        System.out.println(minStack.getMin());
        minStack.push(1);
        System.out.println(minStack.getMin());
    }


}

猜你喜欢

转载自blog.csdn.net/qq_39455116/article/details/82878480