Contents

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

  1. LIFO Property: Stack naturally handles reverse-order matching (parentheses, brackets)
  2. State Preservation: Save state before entering nested structures, restore after exiting
  3. Operator Precedence: Use stack to defer low-precedence operations
  4. Monotonic Order: Maintain sorted order to efficiently find extrema
  5. 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

  1. Forgetting to check empty stack before st.top() or st.pop()
  2. Wrong stack order when pushing/popping multiple values
  3. Not resetting state after processing elements
  4. Index vs value confusion in monotonic stack problems