Should you store indices or values in your monotonic stack? This choice determines whether your solution works.
This guide gives you a simple decision framework to choose correctly every time.
TL;DR
Store indices when:
- ✅ Need to calculate distances (e.g., days until warmer)
- ✅ Need to access original array later
- ✅ Need position information
Store values when:
- ✅ Only need comparisons
- ✅ Don't need distances or positions
- ✅ Want simpler code
Decision tree:
Do you need to calculate i - j (distance)?
├─ YES → Store indices
└─ NO → Continue
Do you need to access original array later?
├─ YES → Store indices
└─ NO → Store values (simpler)When to Store Indices
Use Case 1: Calculating Distances
Problem: Daily Temperatures - find days until warmer temperature
def dailyTemperatures(temperatures):
"""
Need distance: i - idx
→ Store indices
"""
result = [0] * len(temperatures)
stack = [] # Store indices
for i in range(len(temperatures)):
while stack and temperatures[i] > temperatures[stack[-1]]:
idx = stack.pop()
result[idx] = i - idx # Calculate distance!
stack.append(i)
return resultWhy indices: Need i - idx to calculate days.
Use Case 2: Accessing Original Array
Problem: Trapping Rain Water - need to access heights
def trap(height):
"""
Need to access height[stack[-1]] multiple times
→ Store indices
"""
water = 0
stack = [] # Store indices
for i in range(len(height)):
while stack and height[i] > height[stack[-1]]:
bottom = stack.pop()
if not stack:
break
# Access original array multiple times
left_height = height[stack[-1]]
right_height = height[i]
bottom_height = height[bottom]
width = i - stack[-1] - 1
bounded_height = min(left_height, right_height) - bottom_height
water += width * bounded_height
stack.append(i)
return waterWhy indices: Need to access height[] array repeatedly.
Use Case 3: Position Information
Problem: Stock Span - need to track positions
class StockSpanner:
def __init__(self):
self.prices = []
self.stack = [] # Store indices
def next(self, price):
self.prices.append(price)
current_index = len(self.prices) - 1
while self.stack and self.prices[self.stack[-1]] <= price:
self.stack.pop()
# Calculate span using indices
if not self.stack:
span = current_index + 1
else:
span = current_index - self.stack[-1]
self.stack.append(current_index)
return spanWhy indices: Need position to calculate span.
When to Store Values
Use Case 1: Only Need Comparisons
Problem: Remove K Digits - only compare digit values
def removeKdigits(num, k):
"""
Only need to compare digits
→ Store values (simpler)
"""
stack = [] # Store values (characters)
for digit in num:
# Only comparing values, no distance needed
while stack and k > 0 and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
# Remove remaining k digits
if k > 0:
stack = stack[:-k]
result = ''.join(stack).lstrip('0')
return result if result else '0'Why values: Only need to compare digits, no distance calculation.
Use Case 2: Simpler Implementation
Problem: Valid Parentheses - match brackets
def isValid(s):
"""
Only need to match characters
→ Store values (simpler)
"""
stack = [] # Store values (characters)
pairs = {'(': ')', '[': ']', '{': '}'}
for char in s:
if char in pairs:
stack.append(char)
elif not stack or pairs[stack.pop()] != char:
return False
return not stackWhy values: Only matching characters, indices not needed.
Comparison Table
| Aspect | Store Indices | Store Values |
|---|---|---|
| Distance calculation | ✅ Yes (i - idx) | ❌ No |
| Array access | ✅ Yes (arr[idx]) | ❌ No |
| Position tracking | ✅ Yes | ❌ No |
| Code simplicity | ⚠️ More complex | ✅ Simpler |
| Memory | Same (both O(n)) | Same (both O(n)) |
| Use cases | Distances, positions | Comparisons only |
Decision Framework
┌─────────────────────────────────────────────────────────┐
│ STEP 1: Do you need distances (i - j)? │
├─────────────────────────────────────────────────────────┤
│ YES → Store indices │
│ Examples: Daily Temperatures, Stock Span │
└─────────────────────────────────────────────────────────┘
│
↓ NO
┌─────────────────────────────────────────────────────────┐
│ STEP 2: Do you need to access original array? │
├─────────────────────────────────────────────────────────┤
│ YES → Store indices │
│ Examples: Trapping Rain Water, Histogram │
└─────────────────────────────────────────────────────────┘
│
↓ NO
┌─────────────────────────────────────────────────────────┐
│ STEP 3: Do you need position information? │
├─────────────────────────────────────────────────────────┤
│ YES → Store indices │
│ NO → Store values (simpler) │
│ Examples: Remove K Digits, Valid Parentheses │
└─────────────────────────────────────────────────────────┘Problem Classification
Store Indices
- Daily Temperatures (#739) - Distance calculation
- Trapping Rain Water (#42) - Array access
- Largest Rectangle in Histogram (#84) - Width calculation
- Stock Span (#901) - Position tracking
- Next Greater Element (#496) - Index mapping
Store Values
- Remove K Digits (#402) - Digit comparison
- Valid Parentheses (#20) - Character matching
- Remove Duplicate Letters (#316) - Character comparison
- Smallest Subsequence (#1081) - Character comparison
Conclusion
Simple rule:
- Need distances/positions? → Store indices
- Only comparisons? → Store values
The decision:
# If you need this:
distance = i - idx # Store indices
# If you only need this:
if value1 > value2: # Store valuesNext steps:
Want to Practice LeetCode Smarter?
LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.
Also compatible with Edge, Brave, and Opera
