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
————————————————————————————————
这道题刚开始看,以为就是记录一下最小值就行了。后来一细想,发现其实很复杂,每次pop完了最上面的值,还是需要O(1)找到新的min值的。
举个��:
push:3,2,1,2,1. 这时候pop 1出来,如果不加判断或者数据结构和算法设计的不好,会把min=1就给remove了,但其实此时最小的还是1.
想到了一个解决方案,就是弄个新的class,比如叫Node<Integer, Integer>,第一个int存的是自己的value,第二个integer存的是到它进来前最小的value。然后有一个公共的min,如果push进来的新元素比旧的min小,那么就更新它。写下来大概其是这样的:
public class minStack{
int min;
Stack<> stack;
}
class Node{
int val;
int pre_min;
Node(int a, int b){
val =a;
pre_min = b;
}
}
这样设计应该是没问题,但是我又发现。。。自己多年前做过这道题,而且自己曾经的做法还非常巧妙。。。
就是每次push进去一个数之前,先比较是不是比之前的min小,如果是,先把min push进去,再push 这个数。
这样每次pop出最小数的时候,判断是不是此数值==min,如果是,多pop一个出来(即刚才发进去的次数push之前的min),把这个值赋给min。
package testAndfun;
import java.util.ArrayList;
import java.util.Stack;
class MinStack {
Stack<Integer> stack = new Stack<Integer>();
int min;
public static void main(String args[]){
MinStack ms = new MinStack();
ms.push(2);
ms.push(1);
ms.push(2);
ms.push(1);
System.out.println(ms.getMin());
ms.pop();
//System.out.println(ms.pop(););
System.out.println(ms.getMin());
}
public void push(int x) {
if(stack.empty()||x<=min){
stack.push(min);//这个东西相当于在记录push之前最小值
stack.push(x);
min = x;//这个东西相当于在记录push之后最小值
}
else stack.push(x);
}
public void pop() {
int tmp = stack.pop();
if(tmp==min)
min=stack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return min;
}
}