Design a max stack that supports push, pop, top, peekMax and popMax.
- push(x) -- Push element x onto stack.
- pop() -- Remove the element on top of the stack and return it.
- top() -- Get the element on the top.
- peekMax() -- Retrieve the maximum element in the stack.
- popMax() -- Retrieve the maximum element in the stack, and remove it. If you find more than one maximum elements, only remove the top-most one.
Stack
class MaxStack {
private Stack<Integer> num;
private Stack<Integer> max;
/** initialize your data structure here. */
public MaxStack() {
this.num = new Stack<Integer>();
this.max = new Stack<Integer>();
}
public void push(int x) {
int max = this.max.size() > 0 ? this.max.peek() : x;
this.num.push(x);
this.max.push(Math.max(x, max));
}
public int pop() {
int res = this.num.pop();
this.max.pop();
return res;
}
public int top() {
return this.num.peek();
}
public int peekMax() {
return this.max.peek();
}
public int popMax() {
int max = this.max.peek();
Stack<Integer> s1 = new Stack<>();
while(this.num.peek() != max) {
s1.push(this.num.pop());
this.max.pop();
}
this.num.pop();
this.max.pop();
while(s1.size() > 0) {
this.push(s1.pop());
}
return max;
}
}
/**
* Your MaxStack object will be instantiated and called as such:
* MaxStack obj = new MaxStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.peekMax();
* int param_5 = obj.popMax();
*/
Double linked list + treemap
class MaxStack {
class Node {
public int val;
public Node prev;
public Node next;
public Node(int v) {
this.val = v;
this.prev = null;
this.next = null;
}
}
private Node head;
private Node tail;
private TreeMap<Integer, List<Node>> map;
/** initialize your data structure here. */
public MaxStack() {
this.head = new Node(0);
this.tail = new Node(0);
this.head.next = this.tail;
this.tail.prev = this.head;
this.map = new TreeMap<Integer, List<Node>>();
}
public void push(int x) {
Node node = new Node(x);
node.next = this.tail;
node.prev = this.tail.prev;
this.tail.prev.next = node;
this.tail.prev = node;
if(!this.map.containsKey(x))
this.map.put(x, new ArrayList<Node>());
this.map.get(x).add(node);
}
public int pop() {
Node temp = this.tail.prev;
temp.prev.next = this.tail;
this.tail.prev = temp.prev;
temp.next = null;
temp.prev = null;
List<Node> list = map.get(temp.val);
list.remove(list.size() - 1);
if(list.size() == 0)
map.remove(temp.val);
return temp.val;
}
public int top() {
return this.tail.prev.val;
}
public int peekMax() {
return this.map.lastKey();
}
public int popMax() {
List<Node> list = map.get(map.lastKey());
Node n = list.remove(list.size() - 1);
if(list.size() == 0)
map.remove(n.val);
n.prev.next = n.next;
n.next.prev = n.prev;
n.next = null;
n.prev = null;
return n.val;
}
}
/**
* Your MaxStack object will be instantiated and called as such:
* MaxStack obj = new MaxStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.peekMax();
* int param_5 = obj.popMax();
*/