我们都知道一个栈的特点是后进先出,如果我们要实现在O(1)的时间内找到一个栈里面的最小值,我们应该怎么解决?如果我们采用遍历获取的思路那必然所需要的时间是O(N)与我们所需要的要求明显不符合,这时候我们通常需要采用的是和前面我们介绍到的栈的压入弹出序列相类似,采用辅助栈的思想。我们不妨构建一个辅助栈,当我们在栈压入数据时,就和辅助栈里面的最小值比较,如果大就存入栈里面的最小值,如果小我们就存入这个数据。我们的辅助栈是每存入一个数据的时候就存入一个当前数据结构的最小值,为了避免我们遇到一个问题,就是在最小值弹出以后我们找不到最小值的尴尬,所以辅助栈的栈顶元素应该随着压栈和弹栈的操作同时进行。有了思路我们的代码如下:
public class MyStack(){ //自定义一个栈 private int size; private int min = Integer.MAX_VALUE; private Integer[] elements = new Integer[10]; private Stack minStack<Integer> = new Stack<>(); //当一个数据插入栈 public void push(int num){ //对数组进行扩容处理 ensureCapaCity(size) elements[size++] = num; //对辅助栈的数据进行操作 if(num > min){ minStack.push(min); }else{ minStack.push(num); min = minStack.peek(); } } //数组的扩容方法 public void ensureCapaCity(int length){ if(length >= elements.length){ length = (length * 3) / 2 + 1; elements = Arrays.copyOf(elements,length); } } //进行弹出操作 public int pop(){ if(size != 0){ elements[size - 1] = null; size -= 1; int p = minStack.pop(); min = minStack.peek(); return p; } throw New Expection("栈长度为0"); } //min函数的最小值 public int min(){ return min; } }
我们在这里主要需要我们去理解的是借助于辅助栈,对每插入一个数据进行一轮最小值的储存,当栈里面的元素被弹出时我们辅助栈里面的栈顶元素也会随之而改变。