Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- getMin() -- Retrieve the minimum element in the stack.
思路一:
用一个栈存数值,在用一个栈存当前的最小值即可,空间上第二个栈可以做一下优化,即当数值栈push进或者pop出的数值大于当前的最小值的话最小值栈是不用做任何操作的。
1 public class MinStack { 2 3 Stack<Integer> stackNum = new Stack<Integer>(); 4 Stack<Integer> stackMin = new Stack<Integer>(); 5 6 public void push(int x) { 7 stackNum.push(x); 8 if(stackMin.isEmpty() || stackMin.peek() >= x) { 9 stackMin.push(x); 10 } 11 } 12 13 public void pop() { 14 int top = stackNum.pop(); 15 if(top <= stackMin.peek()) { 16 stackMin.pop(); 17 } 18 } 19 20 public int top() { 21 return stackNum.peek(); 22 } 23 24 public int getMin() { 25 return stackMin.peek(); 26 } 27 }
思路二:
比较巧妙的一种思路,可以不用最小值栈。
每当push操作时,压入当前元素与当前最小值的差值,然后将其与当前最小值中小的那个压入栈顶,所以当前栈顶元素一直是当前最小值。
每当pop操作时,pop出栈顶的两个值,分别是当前最小值min和最后压入栈中与其压入栈时栈中最小值得差值dif,如果dif<0,则说明当前栈中最小值就是最后压入栈的元素,所以该元素出站之后栈中的最小值变为min-dif,只需再将min-dif压入栈顶作为最小值即可,如需返回栈顶元素则是min,如果dif>=0,则说明当前栈中最小值与栈顶元素无关,所以该元素出栈之后栈中最小值还是min,只需再将min压入栈顶作为最小值即可,如需返回栈顶元素则是min+dif。
需要注意的是,两个int的差值有可能会越界,所以栈中存的是Long类型元素。
1 public class MinStackII { 2 Stack<Long> stack = new Stack<Long>(); 3 public void push(int x) { 4 if(stack.isEmpty()) { 5 stack.push(0L); 6 stack.push((long)x); 7 } else { 8 Long min = stack.pop(); 9 stack.push(x - min); 10 stack.push(x < min ? x : min); 11 } 12 } 13 14 public void pop() { 15 Long min = stack.pop(); 16 Long dif = stack.pop(); 17 if(dif < 0) { 18 stack.push(min - dif); 19 } else { 20 if(!stack.isEmpty()) stack.push(min); 21 } 22 } 23 24 public int top() { 25 Long min = stack.pop(); 26 Long dif = stack.pop(); 27 stack.push(dif); 28 stack.push(min); 29 if(dif < 0) return min.intValue(); 30 else return (int)(min + dif); 31 } 32 33 public int getMin() { 34 return stack.peek().intValue(); 35 } 36 37 }