public class MinStack {
/** initialize your data structure here. */
private TreeMap<Integer, Integer> min;//用TreeMap来对min的序列有序排列
private LinkedList<Integer> stack;
public MinStack() {
min = new TreeMap<>();
stack = new LinkedList<>();
}
public void push(int x) {
stack.add(x);
if(min.containsKey(x)){
min.put(x, min.get(x) + 1);//相同的key会覆盖,map.get(key)返回的是key的value
}
else{
min.put(x, 1);
}
}
public void pop() {
int pop = stack.removeLast();
//min.remove(pop);//假如插入时被去重了怎么办,所以用TreeMap的value来记录出现次数
if(min.get(pop) == 1){
min.remove(pop);
}
else{
min.put(pop, min.get(pop) - 1);
}
}
public int top() {
return stack.getLast();
}
public int getMin() {
return min.firstKey();//因为TreeMap是有序的,所以TreeMap的第一个元素就是最小值
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
解法二:
public class MinStack {
/** initialize your data structure here. */
private int min;//比起解法一
// only push the old minimum value when the current minimum value [changes] after pushing the new value x
private LinkedList<Integer> stack;
public MinStack() {
min = Integer.MAX_VALUE;//让min初始化为最大后面才好更新
stack = new LinkedList<>();
}
public void push(int x) {
// only push the old minimum value when the current minimum value [changes] after pushing the new value x
if(x <= min){
stack.add(min);//压入旧的min值,因为栈的最底部是Integer.MAX_VALUE,若要继续完善,所以计数时判断isEmpty基数是1
min = x;//压栈过程中更新min的值
}
stack.add(x);//正常压入元素,先压入旧的min,后压入元素
}
public void pop() {
int pop = stack.removeLast();
if(pop == min){//说明弹出的元素是min
min = stack.removeLast();//找一个旧的min来给min,因为压入时【先压入旧的min,后压入元素】
}
}
public int top() {
return stack.getLast();
}
public int getMin() {
return min;
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
解法三:
public class MinStack {
/** initialize your data structure here. */
private long min;//因为这里存在差值,所以用long来存,防止溢出
private LinkedList<Long> stack;
public MinStack() {
min = Long.MAX_VALUE;
stack = new LinkedList<>();
}
public void push(int x) {
//解法三:压入栈的第一个元素是0(因为此时min - x =0),后面压入栈的是min与元素的差值来代表元素,而min是实际的元素,注意min是实时更新的
if(stack.isEmpty()){
stack.add(0L);
min = x;
}
else{
stack.add(x - min);//以旧的min来作差,因为后面的min会被弹出
if(x <= min){//if(x < min)也行,重复的不影响更新
min = x;//更新min的值
}
}
}
public void pop() {
long p = stack.removeLast();
//if p ==0, it means there are duplicates of min value. after pop, the min value did not change.
if(p < 0){//说明x - min = p < 0,在压入时min更新了,那么弹出时min需要更新到上一层的
min = min - p;
}
}
public int top() {
long t = stack.getLast();
if(t > 0){//说明x - min = t > 0,那么是旧的min
return (int)(t + min);
}
else{//说明x - min = t <= 0,那么min是被更新成了x,min是新的了,直接return min,不能再return (t + min)
return (int)min;
}
}
public int getMin() {
return (int)min;
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/