LeetCode Templates: Stack
Contents
- Parentheses Matching
- Expression Evaluation
- Nested Structure Processing
- Monotonic Stack
- Stack for State Management
Parentheses Matching
Use stack’s LIFO property to match opening and closing brackets in reverse order.
bool isValid(string s) {
stack<char> st;
unordered_map<char, char> map = {
{'}', '{'}, {']', '['}, {')', '('}
};
for(char c: s) {
if(c == '{' || c == '[' || c == '(') {
st.push(c);
} else {
if(st.empty() || st.top() != map[c]) return false;
st.pop();
}
}
return st.empty();
}
| 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.
int calculate(string s) {
stack<int> stk;
int result = 0, num = 0, sign = 1;
for(char c: s) {
if(isdigit(c)) {
num = num * 10 + (c - '0');
} else if(c == '+' || c == '-') {
result += sign * num;
sign = (c == '+') ? 1 : -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.
string decodeString(string s) {
stack<string> st;
string curr = "";
int k = 0;
for(char c: 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 == ']') {
string prev = st.top(); st.pop();
int count = stoi(st.top()); st.pop();
string temp = "";
for(int i = 0; i < count; i++) 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.
vector<int> nextGreater(vector<int>& nums) {
int n = nums.size();
vector<int> result(n, -1);
stack<int> st;
for(int i = 0; i < n; i++) {
while(!st.empty() && nums[st.top()] < nums[i]) {
result[st.top()] = nums[i];
st.pop();
}
st.push(i);
}
return result;
}
| ID | Title | 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 |
Stack for State Management
Use stack to save and restore state when processing nested or hierarchical structures.
// Example: Tracking function call stack
void processLogs(vector<string>& logs) {
stack<pair<int, int>> st; // {function_id, start_time}
vector<int> result(n, 0);
for(string& log: logs) {
// Parse log entry
if(isStart) {
st.push({id, time});
} else {
auto [funcId, startTime] = st.top();
st.pop();
int duration = time - startTime + 1;
result[funcId] += duration;
// Subtract from parent if exists
if(!st.empty()) {
result[st.top().first] -= duration;
}
}
}
}
| ID | Title | Link | Solution |
|---|---|---|---|
| 636 | Exclusive Time of Functions | Link | Solution |
| 394 | Decode String | Link | Solution |
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