Min Stack Design in DSA Python - Time & Space Complexity
We want to understand how fast the Min Stack operations run as the number of elements grows.
Specifically, how the time to push, pop, or get the minimum changes with more items.
Analyze the time complexity of the following Min Stack implementation.
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, val):
self.stack.append(val)
if not self.min_stack or val <= self.min_stack[-1]:
self.min_stack.append(val)
def pop(self):
if self.stack:
val = self.stack.pop()
if val == self.min_stack[-1]:
self.min_stack.pop()
def get_min(self):
return self.min_stack[-1] if self.min_stack else None
This code keeps track of the minimum value at each step using a second stack.
Look at the main operations that repeat when the stack changes.
- Primary operation: Adding or removing elements from the main and min stacks.
- How many times: Each push or pop runs once per call, no loops inside.
Each operation does a fixed number of steps regardless of stack size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 push or pop steps |
| 100 | 100 push or pop steps |
| 1000 | 1000 push or pop steps |
Pattern observation: The time per operation stays the same no matter how big the stack is.
Time Complexity: O(1)
This means each push, pop, or get_min operation takes the same short time no matter how many items are in the stack.
[X] Wrong: "Finding the minimum must check all elements, so it takes longer as the stack grows."
[OK] Correct: The min stack keeps track of minimums as we go, so get_min just looks at the top of min_stack instantly.
Knowing how to keep track of minimums efficiently shows you can design smart data structures that save time.
This skill helps you solve problems where quick access to special values is needed.
"What if we stored minimums only when they change, not every time? 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 support normal stack operations and also return the minimum element quickly.Step 2: Identify the key feature
The key feature is retrieving the minimum element in constant time, not sorting or reversing.Final Answer:
To retrieve the minimum element in constant time along with stack operations -> Option CQuick Check:
Min Stack = fast minimum retrieval [OK]
- Thinking Min Stack sorts elements
- Assuming it stores only minimum elements
- Confusing with reversing stack order
Solution
Step 1: Check correct attribute initialization
Attributes must be initialized withselfto be instance variables.Step 2: Verify list initialization
Bothstackandmin_stackshould be empty lists initialized withself.Final Answer:
class MinStack:\n def __init__(self):\n self.stack = []\n self.min_stack = [] -> Option DQuick Check:
Use self for instance variables [OK]
- Not using self for attributes
- Initializing attributes as None instead of lists
- Assigning self to a list directly
min_stack = MinStack() min_stack.push(3) min_stack.push(5) min_stack.push(2) min_stack.push(1) min_stack.pop() print(min_stack.get_min())
Solution
Step 1: Trace push operations and min tracking
Push 3 (min=3), push 5 (min=3), push 2 (min=2), push 1 (min=1).Step 2: Pop removes 1, min updates to 2
After popping 1, the minimum is the next smallest, which is 2.Final Answer:
2 -> Option AQuick Check:
Pop removes min 1, next min = 2 [OK]
- Assuming min stays 1 after pop
- Confusing push order with min updates
- Ignoring min stack updates on pop
pop method and choose the correct fix:
def pop(self):
if self.stack:
self.stack.pop()
self.min_stack.pop()Solution
Step 1: Understand pop logic in Min Stack
Pop from min_stack only if the popped element is the current minimum to keep min_stack accurate.Step 2: Identify bug and fix
Current code always pops min_stack, which can cause errors if min_stack is out of sync.Final Answer:
Pop from min_stack only if popped element equals current min -> Option BQuick Check:
Pop min_stack conditionally to keep min correct [OK]
- Always popping min_stack without condition
- Not checking min_stack emptiness
- Changing pop order incorrectly
push, pop, top, and get_min all in O(1) time. Which approach is best?Solution
Step 1: Analyze time complexity requirements
All operations must be O(1), so scanning or traversing is not allowed.Step 2: Choose data structure approach
Using two stacks, one for elements and one for minimums, allows constant time min retrieval.Final Answer:
Use two stacks: one for all elements, one for current minimums -> Option AQuick Check:
Two stacks = O(1) min retrieval [OK]
- Using scanning which is O(n)
- Using queue which doesn't support stack operations
- Using linked list traversal for min
Ready to prove it?
Pass the test and this pattern moves unknown
