【左程云算法09】栈的入门题目-最小栈
目录
栈的入门题目-最小栈
代码演示
视频链接
算法讲解015【入门】栈的入门题目-最小栈
Leecode155
栈的入门题目-最小栈
实现一个getmin方法(高效方法,即不用遍历),希望能实现O(1)
做法:准备两个栈
data和min栈
当我压入3时,我同步压入。
如果再加入个5,data栈压入5。让最小栈的栈顶和要压入的数比较。3<5,所以min栈再压入5。
比如再压入2,2现在是最小的,所以左右同时压入2。
比如再压入7,2目前还是最小的,所以左边压入7,右边压入2。
总结:就这三条逻辑
1)当前压的数字<=min栈的顶,当前数字压入min栈
2)当前压得数字>min栈的顶,min原来的数压入min栈
3)min栈为空,data为空,当前要压的数字压入min栈
为什么要这么做?
保证一一对应。即永远右边的栈顶是栈里元素的最小值。
要弹出的时候,data栈和min栈同步弹出就行
代码演示
import java.util.Stack;
public class MinStack1 {//data栈:用于存放所有实际的数字public Stack<Integer>data;//min栈:辅助栈,其栈顶永远是当前data栈中的最小值public Stack<Integer>min;//构造方法:public MinStack1(){//初始化两个栈data = new Stack<Integer>();min = new Stack<Integer>();}/*** 将一个元素推入栈中*/public void push(int val){//第一步:无论如何,新元素val总是要被推入data栈data.push(val);//第二步:根据规则决定往min栈中推入什么//条件一:min栈为空?(即这是第一个元素,它当然是最小值)//条件二:val<=min.peek()? 如果是的话,那么目前val最小,val压入到min栈中。//条件一条件二都是将val直接压入min栈中if(min.isEmpty()||val<=min.peek()){min.push(val);}else{//如果是条件三:即min.peek比val要小,那么再把它压一遍min.push(min.peek());}}/*** 从栈中弹出一个元素*/public void pop(){//data栈和min栈是严格同步的,所以data栈弹出时min栈也应该弹出,以维持同步data.pop();min.pop();}/*** 查看栈顶元素*/public int top(){//栈顶元素就是data栈的栈顶return data.peek();}/*** 获取栈的最小元素*/public int getMin() {//即min的peekreturn min.peek();}
}
但这种方法(即用java自带的stack类效率低),所以我们选择用数组来亲手搭建一个栈,这样效率高。
public class MinStack2 {//假设这个栈最多装8001个元素public final int MAXN = 8001;//用两个整型数组来代替stack类public int[]data;//对应之前的data栈public int[]min;//对应之前的min栈//变量size:即表示当前元素的数量,也指向下一个要插入的位置int size;//构造方法public MinStack2(){//创建两个刚好能容纳MAXN个整数的数组//相当于建好了两怕空的储物柜data = new int[MAXN];min = new int[MAXN ];//初始时一个元素都没有所以size是0size = 0;}/*** 将一个元素推入我们用数组模拟的栈中*/public void push(int val){//data[size] = val//把新元素val放入data数组的第size个位置//如果size是0,就放在data[0];如果size是1,就放在data[1]data[size] = val;//data栈压入之后,我们来想一想min栈怎么办(和上一题一样)if(size == 0||val<=min[size-1]){min[size] = val;}else{//否则,最小值不变//复制上一个位置的最小值到当前位置,以保持和data数组的同步min[size] = min[size-1];}//最重要的一步:把size加1,让指针指向下一个空位//并且表示元素总数增加一个size++;}/*** 从我们用数组模拟的栈中弹出一个元素*/public void pop(){//我们不需要真的去清除数组里的data[size-1]//只需要把size减1,就等于我们逻辑上抛弃了最后一个元素//下次push时,那个位置的值会被自然地覆盖掉size--;}/*** 查看栈顶元素*/public int top(){//因为size指向地是下一个空位,所以栈真正地顶部元素位于它地前一个位置// 即size-1return data[size-1];}/*** 获取栈中的最小元素*/public int getMin(){//同理,最小元素即min数组的栈顶位置,也就是size-1return min[size-1];}
}