Min Stack Design in DSA C++ - Time & Space Complexity
We want to understand how fast the Min Stack operations run as we add more elements.
Specifically, how does the time to push, pop, or get the minimum change with more data?
Analyze the time complexity of the following Min Stack implementation.
class MinStack {
std::stack<int> mainStack, minStack;
public:
void push(int x) {
mainStack.push(x);
if(minStack.empty() || x <= minStack.top())
minStack.push(x);
}
void pop() {
if(mainStack.top() == minStack.top())
minStack.pop();
mainStack.pop();
}
int getMin() {
return minStack.top();
}
};
This code keeps track of the minimum element using an extra stack alongside the main stack.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Each push, pop, and getMin call does a fixed number of stack operations.
- How many times: Each operation runs once per call, no loops inside these methods.
Each operation does a constant amount of work regardless of how many elements are in the stack.
| Input Size (n) | Approx. Operations per call |
|---|---|
| 10 | 2-3 stack operations |
| 100 | 2-3 stack operations |
| 1000 | 2-3 stack operations |
Pattern observation: The time per operation stays the same no matter how big the stack grows.
Time Complexity: O(1)
This means each push, pop, or getMin operation takes the same short time no matter how many elements are stored.
[X] Wrong: "Finding the minimum must scan the whole stack, so it takes longer as the stack grows."
[OK] Correct: The extra minStack keeps track of minimums so getMin just looks at the top, no scanning needed.
Understanding how to keep track of minimums efficiently shows you can design smart data structures that save time.
This skill is useful for many problems where quick access to special values is needed.
"What if we stored minimums only when they change, instead of every push? How would that affect time complexity?"
Practice
Min Stack data structure?Solution
Step 1: Understand the Min Stack concept
A Min Stack is designed to keep track of the minimum element efficiently.Step 2: Identify the key feature
It allows retrieving the minimum element in constant time, unlike a normal stack.Final Answer:
To retrieve the minimum element in constant time -> Option BQuick Check:
Min Stack purpose = retrieve minimum element fast [OK]
- Confusing Min Stack with sorting
- Thinking it behaves like a queue
- Assuming it reverses elements
Solution
Step 1: Recall C++ stack declaration syntax
The correct syntax uses template with angle brackets and variable name after.Step 2: Check each option
stack<int> s; matches correct syntax:stack<int> s;. Others have syntax errors.Final Answer:
stack<int> s; -> Option CQuick Check:
C++ stack declaration = stack<int> s; [OK]
- Placing variable name inside angle brackets
- Using parentheses instead of semicolon
- Declaring as array without initialization
void push(int x) {
s.push(x);
if (minStack.empty() || x <= minStack.top()) {
minStack.push(x);
}
}
What will be the content of minStack after pushing the sequence [3, 5, 2, 2, 4]?Solution
Step 1: Trace push operations on minStack
Push 3: minStack empty, push 3 -> [3] Push 5: 5 > top(3), no push -> [3] Push 2: 2 <= 3, push 2 -> [3, 2] Push 2: 2 <= 2, push 2 -> [3, 2, 2] Push 4: 4 > 2, no push -> [3, 2, 2]Step 2: Confirm final minStack content
minStack contains [3, 2, 2] after all pushes.Final Answer:
[3, 2, 2] -> Option DQuick Check:
minStack after pushes = [3, 2, 2] [OK]
- Pushing all elements to minStack
- Not pushing duplicates of min
- Confusing minStack with main stack
pop() operation of a Min Stack. Identify the error:
void pop() {
if (s.top() == minStack.top()) {
minStack.pop();
}
s.pop();
}Solution
Step 1: Analyze pop operation safety
The code pops from stacks without checking if they are empty, risking runtime errors.Step 2: Identify missing safety checks
Before callingtop()orpop(), stacks should be checked for emptiness.Final Answer:
It does not check if stacks are empty before popping -> Option AQuick Check:
Pop safety requires empty checks [OK]
- Ignoring empty stack checks
- Misusing comparison operators
- Popping stacks in wrong order
push, pop, top, and getMin all in O(1) time. Which approach below correctly achieves this with minimal extra space?Solution
Step 1: Understand O(1) min retrieval requirement
To get minimum in constant time, we must track minimums during push/pop without scanning.Step 2: Evaluate approaches
Use one stack to store values and a second stack to store minimums only when a new minimum is pushed uses a second stack to store minimums only when a new minimum appears, saving space and ensuring O(1) operations.Final Answer:
Use one stack to store values and a second stack to store minimums only when a new minimum is pushed -> Option AQuick Check:
Min Stack with minimal space = two stacks, min pushed selectively [OK]
- Sorting stack after each push (slow)
- Scanning stack to find min (not O(1))
- Using queue which breaks stack order
Ready to prove it?
Pass the test and this pattern moves unknown
