简单双栈实现
增加一个minStack 用以维持 此时的最小值,每次push进栈的同时,将将此时的最小值push到minStack中;同时出栈也将minStack 也出栈。
/**
* 双栈实现
* 空间复杂度 O(n)
*/
import java.util.Stack;
public class Solution {
Stack<Integer> minStack = new Stack<>();
Stack<Integer> stack = new Stack<>();
public void push(int node){
stack.push(node);
if(minStack.isEmpty())
minStack.push(node);
else{
minStack.push(Math.min(minStack.peek(), node));
}
}
public void pop(){
if(stack.isEmpty())
return;
stack.pop();
minStack.pop();
}
public int top(){
if(stack.isEmpty())
return -1;
return stack.peek();
}
public int min(){
if(stack.isEmpty())
return -1;
return minStack.peek();
}
}
压缩还原法(不用冗余的栈)
我们发现其实最小值min它本身就是一种冗余信息。为什么呢?因为每个元素在数值上都包含了min值,举个例子,假设入栈序列为:4、5、6、3、2、1,那么各轮次对应的min值就是:4、4、4、3、2、1,发现有:
4=4+0,5=4+1,6=4+2,3=4+(-1),2=3+(-1),1=2+(-1);各个元素在数值上已经包含了在它之前的最小值的值;
那么,我们是不是只要在数据栈中存储0、1、2、-1、-1、-1,然后再使用一个辅助变量min=1就可以了呢?
这样,根据单个辅助变量和栈中存储的值就能够推理出top值和min值了,具体规则如下:
入栈:
压缩:将要入栈的元素value减去当前最小值min,得到一个差值diff,只存储该差值;
更新:如果入栈的元素value比当前最小值min小,则要更新最小值:min=value;
初始:第一次入栈比较特殊,因为此时的min变量并没有值,所以令:min=value;
出栈:
更新:如果栈中存储的差值diff是负数,说明出栈的元素是当前最小值min,需要把min值更新为上一个最小值min = min - diff,否则,出栈的元素不是最小值,则不对min变量做任何操作;
还原:如果栈中存储的差值diff是正数,说明 top = min + diff,否则,说明top元素本身是最小值 top = min;
/**
* 压缩还原法
* 空间复杂度 O(1)
*/
import java.util.Stack;
public class Solution2 {
Stack<Integer> stack = new Stack<Integer>();
int min;
public void push(int node){
if(stack.isEmpty()){
min = node;
stack.push(node - min);
}else{
int diff = node - min;
stack.push(diff);
if(diff < 0)
min = node;
}
}
public void pop(){
if(stack.isEmpty())
return;
int diff = stack.pop();
if(diff < 0){
min = min - diff;
}
}
public int top(){
if(stack.isEmpty())
return -1;
int diff = stack.peek();
if(diff < 0){
return min;
}
return min + diff;
}
public int min(){
if(stack.isEmpty())
return -1;
return min;
}
}