859. Max Stack
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.
Example
Input:
push(5)
push(1)
push(5)
top()
popMax()
top()
peekMax()
pop()
top()
Output:
5
5
1
5
1
5
Notice
-1e7 <= x <= 1e7
- Number of operations won't exceed
10000
. - The last four operations won't be called when stack is empty.
Input test data (one parameter per line)How to understand a testcase?
解法1:采用stack和multiset。因为multiset支持erase操作,priority_queue不支持。
注意:
1)C++ multiset, 如果参数是iterator,只删除对应iterator的元素;如果参数是值,删掉所有等于该值的元素。
2) *m.rbegin(); 可返回set/multiset最大值。也可以用*(m.end()-1)。
但注意,multiset的erase()支持iterator参数,但不支持reverse iterator rbegin(),也不支持m.end()-1这种操作。
class MaxStack {
public:
MaxStack() {
}
/*
* @param number: An integer
* @return: nothing
*/
void push(int number) {
s.push(number);
max_heap.insert(number);
}
/*
* @return: An integer
*/
int pop() {
int top = s.top();
s.pop();
int count = max_heap.count(top);
max_heap.erase(top);
if (count > 1) {
for (int i = 1; i < count; ++i) {
max_heap.insert(top);
}
}
return top;
}
/*
* @return: An integer
*/
int top() {
return s.top();
}
/*
* @return: An integer
*/
int peekMax() {
return *max_heap.rbegin(); //or *(max_heap.end() - 1)
}
/*
* @return: An integer
*/
int popMax() {
int max_elem = peekMax();
int count = max_heap.count(max_elem);
//max_heap.erase(max_heap.rbegin());
//max_heap.erase(max_heap.end() - 1);
max_heap.erase(max_elem);
for (int i = 1; i < count; ++i) {
max_heap.insert(max_elem);
}
stack<int> s2;
while(s.top() != max_elem) {
s2.push(s.top());
s.pop();
}
s.pop();
while(!s2.empty()) {
s.push(s2.top());
s2.pop();
}
return max_elem;
}
private:
stack<int> s;
//priority_queue<int> max_heap;
multiset<int> max_heap;
};
二刷:跟min stack一样,还是用两个栈来实现。注意这里不能采用min stack的空间优化算法,这里maxStk和dataStk必须同时都push和pop,而不是只有当number > peerMax()才push和dataStkTop==peerMax()才pop。因为这题要用到popMax(),我们必须维护每个数据对应的max。
class MaxStack {
public:
MaxStack() {
// do intialization if necessary
}
/*
* @param number: An integer
* @return: nothing
*/
void push(int number) {
dataStk.push(number);
if (maxStk.empty()) {
maxStk.push(number);
} else {
maxStk.push(max(number, peekMax()));
}
}
/*
* @return: An integer
*/
int pop() {
int dataStkTop = top();
dataStk.pop();
maxStk.pop();
return dataStkTop;
}
/*
* @return: An integer
*/
int top() {
return dataStk.top();
}
/*
* @return: An integer
*/
int peekMax() {
return maxStk.top();
}
/*
* @return: An integer
*/
int popMax() {
stack<int> tmpStk;
int maxNum = peekMax();
while (top() != maxNum) {
tmpStk.push(pop());
}
pop();
while (!tmpStk.empty()) {
push(tmpStk.top());
tmpStk.pop();
}
return maxNum;
}
private:
stack<int> dataStk;
stack<int> maxStk;
};