Max Stack

Stack with O(log n) popMax — ordered map of value to iterators into a linked list keeping insertion order.

Hard
Time O(log n) popMax Space O(n)
LeetCode
4 min read
design stack ordered-map

Problem#

Implement a stack supporting push, pop, top, peekMax, and popMax. popMax removes the topmost occurrence of the current maximum.

Examples#

  • push(5); push(1); push(5); peekMax()5; popMax()5 (top one), top()1.

Constraints#

  • -10^7 <= x <= 10^7, up to 10^4 calls.

Approach#

Doubly linked list of (value) in stack order. Multimap from value to iterator (one entry per occurrence). popMax consults the multimap’s last bucket, takes the last iterator stored (most recent push of that value), erases from both structures.

Solution#

Max Stack
class MaxStack {
list<int> lst;
map<int, vector<list<int>::iterator>> mp;
public:
void push(int x) {
lst.push_back(x);
mp[x].push_back(prev(lst.end()));
}
int pop() {
int x = lst.back();
mp[x].pop_back();
if (mp[x].empty()) mp.erase(x);
lst.pop_back();
return x;
}
int top() { return lst.back(); }
int peekMax() { return mp.rbegin()->first; }
int popMax() {
int x = mp.rbegin()->first;
auto it = mp[x].back();
mp[x].pop_back();
if (mp[x].empty()) mp.erase(x);
lst.erase(it);
return x;
}
};

Editorial#

The ordered map gives O(log n) access to the current max; storing iterators per bucket lets us remove the topmost occurrence in O(1) once located. Iterators into std::list survive any other-element erase, so they stay valid forever.

Complexity#

  • Time: O(log n) for popMax/peekMax, O(1) otherwise.
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.