剑指 Offer 30. 包含min函数的栈
题解1-双栈
思路
用一个主栈以及一个辅助栈来实现这个功能,主栈负责主要的pop,push,辅助栈用来记录min。
其中:
- push: 如果min栈为空,或压入的元素大于min栈的栈顶元素,则也将x压入min栈,注意这里需要用大于等于号,因为如果只是大于号,连续压入两个相同的最小值,再弹出一个最小值就会出错
- pop:如果主栈pop出的元素与min栈的栈顶元素相同,则min也pop
- top:获取主栈的栈顶元素
- min:获取min栈的栈顶元素
代码
class MinStack {
Stack<Integer> res;
Stack<Integer> min;
/** initialize your data structure here. */
public MinStack() {
res=new Stack<Integer>();
min=new Stack<Integer>();
}
public void push(int x) {
res.push(x);
if(min.isEmpty()||min.peek()>=x)
//如果不加等号的话,连续输入压入两个相同的最小值再弹出一个后,min栈中就没有这个最小值了
min.push(x);
}
public void pop() {
if(res.pop().equals(min.peek()))
//这里用“==”就会出错!!!
min.pop();
}
public int top() {
return res.peek();
}
public int min() {
return min.peek();
}
}
知识点
peek与poop
- Stack.peek() 返回栈顶元素。
- Stack.pop() 返回栈顶元素,并在栈中删除它。
Integer.equals()与“==”
注意这里的代码的pop()处如果用"=="取代equals就会出错,这是因为:
- “==”两边都是包装类型时,会直接比较引用地址
- JAVA的Integer有IntegerCache,他会缓存[-128~127]之间的对象,也就是说如果创建的新对象的值在[-128~128]时,会检查是否有已存在的[-128~127],如果有就直接调用,否则才会产生新对象
- 也就是说,如果连续新建两个相同值的Integer,如果值的大小在[-128~127],他们两个用"=="就是相等的,如果在这个范围之外,他们就不是同一个地址,就是不同的。
关于“==”与equals的区别,具体请看这个博主的文章:
https://www.cnblogs.com/mrhgw/p/10449391.html
题解2-单栈
思路
这里的思路就是只用一个栈,而最小值的获取方式为:
- 每当想要压入的x值小于当前的min值时,就将当前的min值压入栈,表示这个位置以下的所有值的最小值。然后再在上面压入当前的x,并把x设为当前的新的min值。
- 每当弹出的值等于当前的min值时,再弹出当前min值下一个的值,这个值也就是之前压进去的这个位置以下的所有值的最小值。
- 其实就是多用了一些空间来存放了多个"从这个位置往下的最小值"
代码
class MinStack {
Stack<Integer> stack;
int min;
/** initialize your data structure here. */
public MinStack() {
this.stack = new Stack<>();
}
public void push(int x) {
if(stack.isEmpty()) {
min = x;
}
if(x <= min){
//压入上一个最小值
stack.push(min);
min = x;
}
stack.push(x);
}
public void pop() {
if(min == stack.pop()){
//读取上一个最小值
min = stack.pop();
}
}
public int top() {
return stack.peek();
}
public int min() {
return min;
}
}
题解3-数组栈
思路
用数组自己实现栈
- pop --> stack[top–]
- push --> stack[++top]
代码
class MinStack {
int[ ] stack;
int min;
int top;
/** initialize your data structure here. */
public MinStack() {
top=-1;
this.stack = new int[40000];
//最坏情况是不断压入更小的值20000次,此时栈需要40000位
}
public void push(int x) {
if(top==-1) {
//栈为空
min = x;
}
if(x <= min){
stack[++top]=min;
min = x;
}
stack[++top]=x;
}
public void pop() {
if(min == stack[top--]){
min = stack[top--];
}
}
public int top() {
return stack[top];
}
public int min() {
return min;
}
}