Reference: LeetCode
Difficulty: Easy

Problem

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.

Example:

1
2
3
4
5
6
7
8
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.

Follow up: All operations in constant time.

Analysis

Two Stacks (violates the condition)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class MinStack {

private Stack<Integer> stack = new Stack<>();
private Stack<Integer> buffer = new Stack<>();
private int min = Integer.MAX_VALUE;

public void push(int x) {
stack.push(x);
if (x < min) {
min = x;
}
}

// takes O(N) time
public void pop() { // assume not empty
int val = stack.pop();
if (val == min) {
// update min (find the new min)
int newMin = Integer.MAX_VALUE; // consider size = 1, min should be reset
// put aside
while (stack.size() > 0) {
int x = stack.pop();
newMin = Math.min(newMin, x);
buffer.push(x);
}
min = newMin;
// put it back
while (temp.size() > 0) {
stack.push(temp.pop());
}
}
}

public int top() { // assume not empty
return stack.peek();
}

// Required O(1)
public int getMin() { // assume not empty
return min;
}
}

Time: pop() takes $O(N)$ time.
Space: $O(N)$

Backup Old Min

  • When pushing x (x <= min), put old min to the stack before pushing x (the new min).
  • When popping x (x == min), pop one more element to get the old min.

Note: x <= min in push is very important. Consider the case pushing [4, 5, 4] (it fails if x < min is applied).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MinStack {

private Stack<Integer> stack = new Stack<>();
private int min = Integer.MAX_VALUE;

public void push(int x) { // there is always a MAX_VALUE at the bottom
if (x <= min) {
stack.push(min);
min = x;
}
stack.push(x);
}

public void pop() { // assume not empty
if (stack.pop() == min) {
min = stack.pop();
}
}

public int top() { // assume not empty
return stack.peek();
}

public int getMin() { // assume not empty
return min;
}
}

Time: $O(1)$
Space: $O(N)$