DSA Patterns: Stack

LilSardarXLilSardarX
6 min read

The Stack pattern is a go-to tool when you're dealing with nested structures, reverse-order processing, or problems that need memory of what came before.

It’s not just a data structure β€” it’s a mindset. And the more problems you solve with it, the more intuitive it becomes.


πŸ“Œ When to Use the Stack Pattern

Reach for a stack when:

  • You're dealing with balanced expressions (like parentheses or HTML tags)
  • The problem asks for next greater/smaller element
  • You need to track order of things (especially in reverse)
  • You’re simulating undo/redo, function calls, or evaluation logic

🌍 Real-World Use Cases

To internalize the power of a stack, just look around:

  • Undo/Redo in editors β†’ Each action is pushed/popped
  • Browser history β†’ Last visited page is the first to go back to
  • Call stack in programming β†’ Tracks recursive function calls
  • Expression evaluators β†’ Stack is used to evaluate math like ["2", "1", "+", "3", "*"]
  • Maze/DFS traversal β†’ Paths are pushed as you go deeper, popped to backtrack

🧠 Core Idea

Stacks are LIFO β€” Last In, First Out.

At every point, the top of the stack is the most recent item you're still waiting to resolve.

When that condition is satisfied, you pop it and move on.


πŸ§ͺ Problem 1: Valid Parentheses

Leetcode 20 - Valid Parentheses
πŸ‘‰ https://leetcode.com/problems/valid-parentheses/

🧩 The Problem

Given a string containing only '(', ')', '{', '}', '[', ']', determine if the input is valid (i.e., well-formed and properly nested).

🚫 Brute Force

Try matching pairs manually, but this falls apart with nesting and multiple types.

βœ… Why Stack Works

  • Push opening brackets
  • On closing, pop and validate the top
  • If anything’s unmatched or out of order β†’ invalid

βœ… Code

public boolean isValid(String s) {
    Stack<Character> stack = new Stack<>();
    for (char c : s.toCharArray()) {
        if (c == '(' || c == '{' || c == '[') {
            stack.push(c);
        } else {
            if (stack.isEmpty()) return false;
            char top = stack.pop();
            if ((c == ')' && top != '(') ||
                (c == '}' && top != '{') ||
                (c == ']' && top != '[')) {
                return false;
            }
        }
    }
    return stack.isEmpty();
}

πŸ§ͺ Dry Run

Input: "({[]})"
Stack evolves:
( β†’ { β†’ [ β†’ pop ] β†’ pop } β†’ pop ) β†’ stack empty β†’ βœ…

πŸ’‘ Takeaway

When things open and close in reverse order, Stack is the cleanest solution.


πŸ§ͺ Problem 2: Daily Temperatures

Leetcode 739 - Daily Temperatures
πŸ‘‰ https://leetcode.com/problems/daily-temperatures/

🧩 The Problem

Given a list of temperatures, return a list where res[i] is the number of days to wait until a warmer temperature.

Return 0 if there is no such future day.

🚫 Brute Force

Check each future day for every temperature β†’ O(nΒ²) time.

βœ… Why Stack Works

You track indices of unresolved days in a monotonic decreasing stack.
When a warmer day comes, resolve all colder days still on top.

βœ… Code

public int[] dailyTemperatures(int[] temps) {
    int n = temps.length;
    int[] res = new int[n];
    Stack<Integer> stack = new Stack<>(); // store indices

    for (int i = 0; i < n; i++) {
        while (!stack.isEmpty() && temps[i] > temps[stack.peek()]) {
            int prevIndex = stack.pop();
            res[prevIndex] = i - prevIndex;
        }
        stack.push(i);
    }

    return res;
}

πŸ§ͺ Dry Run

Input: [73, 74, 75, 71, 69, 72, 76, 73]

- i = 0, temp = 73 β†’ push β†’ stack = [0], res = [0, 0, 0, 0, 0, 0, 0, 0]
No previous temp to compare. Push index 0 to wait for a warmer day.

- i = 1, temp = 74 β†’ pop 0 β†’ res[0] = 1 β†’ push β†’ stack = [1], res = [1, 0, 0, 0, 0, 0, 0, 0]
74 > 73 β†’ pop index 0, set res[0] = 1 (1 day wait). Push 1 to wait for warmer day than 74.

- i = 2, temp = 75 β†’ pop 1 β†’ res[1] = 1 β†’ push β†’ stack = [2], res = [1, 1, 0, 0, 0, 0, 0, 0]
75 > 74 β†’ pop index 1, set res[1] = 1. Push 2 to wait for warmer day than 75.

- i = 3, temp = 71 β†’ push β†’ stack = [2, 3], res = [1, 1, 0, 0, 0, 0, 0, 0]
71 < 75 β†’ can't resolve anything, push 3 and wait.

- i = 4, temp = 69 β†’ push β†’ stack = [2, 3, 4], res = [1, 1, 0, 0, 0, 0, 0, 0]
69 < 71 β†’ still colder than all above, push 4 and wait.

- i = 5, temp = 72 β†’ pop 4 β†’ res[4] = 1 β†’ pop 3 β†’ res[3] = 2 β†’ push β†’ stack = [2, 5], res = [1, 1, 0, 2, 1, 0, 0, 0]
72 > 69 β†’ res[4] = 5 - 4 = 1.  
Then 72 > 71 β†’ res[3] = 5 - 3 = 2. Push 5 to wait for warmer than 72.

- i = 6, temp = 76 β†’ pop 5 β†’ res[5] = 1 β†’ pop 2 β†’ res[2] = 4 β†’ push β†’ stack = [6], res = [1, 1, 4, 2, 1, 1, 0, 0]
76 > 72 β†’ res[5] = 6 - 5 = 1.  
Then 76 > 75 β†’ res[2] = 6 - 2 = 4. Push 6 to wait for warmer than 76.

- i = 7, temp = 73 β†’ push β†’ stack = [6, 7], res = [1, 1, 4, 2, 1, 1, 0, 0]
73 < 76 β†’ can't resolve anything. Push 7 to wait.

βœ… Final res: [1, 1, 4, 2, 1, 1, 0, 0]

πŸ’‘ Takeaway

When you’re waiting for a condition (like a warmer day) and want to resolve earlier values β€” stack gives you the right order.


πŸ“š Coding Templates

βœ… Balanced Brackets

for (char c : input) {
    if (opening) stack.push(c);
    else {
        if (stack is empty OR top doesn’t match) β†’ invalid
        else stack.pop();
    }
}

βœ… Monotonic Stack (Next Greater Element)

for (i from n-1 to 0) {
    while (!stack.empty() && stack.peek() <= nums[i])
        stack.pop();
    result[i] = stack.empty() ? -1 : stack.peek();
    stack.push(nums[i]);
}

βœ… Postfix Expression Evaluation

for (token in input) {
    if (operator) β†’ pop two, compute, push result
    else β†’ parse and push number
}

🎯 Sample Problems to Internalize Stack

ProblemConceptWhy It Helps
Valid ParenthesesBalanced symbolsClassic LIFO
Min StackStack + auxiliary trackingAugment stack logic
Evaluate Reverse Polish NotationPostfix mathReal-life use case
Daily TemperaturesMonotonic StackNext greater logic
Car FleetSimulationStack with sorting
Asteroid CollisionPhysics + StackProcess left-to-right, resolve conflicts
Largest Rectangle in HistogramMonotonic StackStack under pressure (literally)

🧭 Final Thoughts

The Stack pattern is powerful because it allows you to:

  • Remember unresolved work
  • Resolve things in reverse order
  • Handle nested logic cleanly

Once you start solving problems this way, stack-based solutions will feel like second nature.

0
Subscribe to my newsletter

Read articles from LilSardarX directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

LilSardarX
LilSardarX

I’m figuring things out in tech β€” and blogging along the way. I write what I learn, so I can revise it later and maybe help you avoid a few rabbit holes.