Algorithm Templates: Stack
Minimal, copy-paste C++ for parentheses matching, expression evaluation, nested structures, and monotonic stack.
Contents
- Parentheses Matching
- Expression Evaluation
- Nested Structure Processing
- Monotonic Stack
- Stack for State Management
- Stack Design
Parentheses Matching
Use stack’s LIFO property to match opening and closing brackets in reverse order.
def isValid(self, s):
list[char> st
dict[char, char> map = {}
:'', ':', :']', '[', :')', '('
for c in s:
if c == '{' or c == '[' or c == '(':
st.push(c)
else :
if(not st or st.top() != map[c]) return False
st.pop()
return not st
| ID | Title | Link | Solution |
|---|---|---|---|
| 20 | Valid Parentheses | Link | Solution |
| 921 | Minimum Add to Make Valid Parentheses | Link | Solution |
| 1249 | Minimum Remove to Make Valid Parentheses | Link | Solution |
Expression Evaluation
Use stack to handle operator precedence and parentheses in mathematical expressions.
def calculate(self, s):
list[int> stk
result = 0, num = 0, sign = 1
for c in s:
if isdigit(c):
num = num 10 + (c - '0')
else if(c == '+' or c == '-') :
result += sign num
(1 if sign = (c == '+') else -1)
num = 0
else if(c == '(') :
stk.push(result)
stk.push(sign)
result = 0
sign = 1
else if(c == ')') :
result += sign num
result = stk.top() stk.pop()
result += stk.top() stk.pop()
num = 0
return result + sign num
| ID | Title | Link | Solution |
|---|---|---|---|
| 150 | Evaluate Reverse Polish Notation | Link | Solution |
| 224 | Basic Calculator | Link | Solution |
| 227 | Basic Calculator II | Link | Solution |
| 772 | Basic Calculator III | Link | Solution |
Nested Structure Processing
Use stack to process nested structures like strings, expressions, or function calls.
def decodeString(self, s):
list[str> st
str curr = ""
k = 0
for c in s:
if isdigit(c):
k = k 10 + (c - '0')
else if(c == '[') :
st.push(to_string(k))
st.push(curr)
curr = ""
k = 0
else if(c == ']') :
str prev = st.top() st.pop()
count = stoi(st.top()) st.pop()
str temp = ""
for(i = 0 i < count i += 1) temp += curr
curr = prev + temp
else :
curr += c
return curr
| ID | Title | Link | Solution |
|---|---|---|---|
| 394 | Decode String | Link | Solution |
| 636 | Exclusive Time of Functions | Link | Solution |
| 71 | Simplify Path | Link | - |
Monotonic Stack
Maintain a stack with elements in monotonic order (increasing or decreasing) to efficiently find next/previous greater/smaller elements.
def nextGreater(self, nums):
n = len(nums)
list[int> result(n, -1)
list[int> st
for(i = 0 i < n i += 1) :
while not not st and nums[st.top()] < nums[i]:
result[st.top()] = nums[i]
st.pop()
st.push(i)
return result
| ID | Title | Link | Solution |
|---|---|---|---|
| 42 | Trapping Rain Water | Link | Solution |
| 84 | Largest Rectangle in Histogram | Link | Solution |
| 239 | Sliding Window Maximum | Link | Solution |
| 496 | Next Greater Element I | Link | Solution |
| 503 | Next Greater Element II | Link | Solution |
| 316 | Remove Duplicate Letters | Link | Solution |
| 1944 | Visible People in Queue | Link | Solution |
Stack for State Management
Use stack to save and restore state when processing nested or hierarchical structures.
# Example: Tracking function call stack
def processLogs(self, logs):
list[pair<int, int>> st # :function_id, start_time
list[int> result(n, 0)
for log in logs:
# Parse log entry
if isStart:
st.push(:id, time)
else :
[funcId, startTime] = st.top()
st.pop()
duration = time - startTime + 1
result[funcId] += duration
# Subtract from parent if exists
if not not st:
result[st.top().first] -= duration
| ID | Title | Link | Solution |
|---|---|---|---|
| 636 | Exclusive Time of Functions | Link | Solution |
| 394 | Decode String | Link | Solution |
Stack Design (Min/Max Stack)
Maintaining extra information (like minimums or frequencies) alongside the primary stack data.
class MinStack:
list[int> stk, minStk
def push(self, val):
stk.push(val)
if not minStk) minStk.push(val:
else minStk.push(min(minStk.top(), val))
void pop() : stk.pop() minStk.pop()
top() : return stk.top()
getMin() : return minStk.top()
| ID | Title | Link | Solution |
|---|---|---|---|
| 155 | Min Stack | Link | Solution |
| 716 | Max Stack | Link | - |
Key Patterns
- LIFO Property: Stack naturally handles reverse-order matching (parentheses, brackets)
- State Preservation: Save state before entering nested structures, restore after exiting
- Operator Precedence: Use stack to defer low-precedence operations
- Monotonic Order: Maintain sorted order to efficiently find extrema
- Index Tracking: Store indices instead of values when you need position information
When to Use Stack
- ✅ Matching problems (parentheses, brackets, tags)
- ✅ Expression evaluation with precedence
- ✅ Nested structure processing
- ✅ Finding next/previous greater/smaller elements
- ✅ Reversing order or processing in reverse
- ✅ Undo/redo functionality
- ✅ Function call tracking
Common Mistakes
- Forgetting to check empty stack before
st.top()orst.pop() - Wrong stack order when pushing/popping multiple values
- Not resetting state after processing elements
- Index vs value confusion in monotonic stack problems
More templates
- Data structures (monotonic stack/queue): Data Structures & Core Algorithms
- Graph, Search: Graph, Search
- Master index: Categories & Templates