Skip to content

Stack Problems

LeetCode problems and common patterns using stack data structure.

Valid Parentheses problems

def are_brackets_balanced(input_str):
    brackets = set(["(", ")", "[", "]", "{", "}"])
    bracket_map = {"(": ")", "[": "]",  "{": "}"}
    open_par = set(["(", "[", "{"])
    stack = []

    for character in input_str:
        if character not in brackets:
            # Skipping non-bracket characters
            continue
        if character in open_par:
            stack.append(character)
        elif stack and character == bracket_map[stack[-1]]:
                stack.pop()
        else:
            return False
    return len(stack) == 0

Reverse a String

Naive Approach

def reverse_string(string):
    return string[::-1]

Efficient Approach

Using a stack, we can reverse elements by leveraging its LIFO property. The strategy is straightforward: push all the characters to a stack and then pop them out. As a result, we get the reversed string. This helps demonstrate a practical application of stack operations.

def reverse_string(string):
    stack = list(string)
    results = ''

    i = 0
    while i < len(stack):
        results = results + stack.pop()
        i = i + 1
    return results

Postfix Expression Evaluation

In simple terms, a postfix expression is an arithmetic expression where operators are placed after their operands. For example, the expression 2 3 + is a simple postfix expression, which equals 5 when evaluated.

Efficient Approach

We create an empty stack. Then, we iterate over each character operand in the expression. If operand is a number, we push it onto the stack. If operand is an operator, we pop two numbers from the stack, perform the operation, and push the result back onto the stack. After we have processed all characters of the expression, the stack should contain exactly one element, the result of the expression.

def evaluate_postfix(expression):
    stack = []
    for element in expression.split(' '):   
        if element.isdigit():             
            stack.append(int(element))

        else:
            operand2 = stack.pop()
            operand1 = stack.pop()

            if element == '+': stack.append(operand1 + operand2)
            elif element == '-': stack.append(operand1 - operand2)
            elif element == '*': stack.append(operand1 * operand2)
            elif element == '/': stack.append(operand1 / operand2)

    return stack[0]

Daily Temperatures - LeetCode #739

Problem Statement

Given an array of integers temperatures representing daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the i-th day to get a warmer temperature. If there is no future day for which this is possible, keep answer[i] == 0.

Example:

Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]

For each day, find how many days you'll have to wait until the next warmer day:

  • Day 0 (73°): Next warmer is day 1 (74°) → wait 1 day
  • Day 1 (74°): Next warmer is day 2 (75°) → wait 1 day
  • Day 2 (75°): Next warmer is day 6 (76°) → wait 4 days
  • Day 3 (71°): Next warmer is day 5 (72°) → wait 2 days
  • And so on...

Monotonic Stack Solution

This is a classic monotonic stack problem. We use a decreasing monotonic stack to efficiently find the next warmer temperature.

def dailyTemperatures(temperatures):
    result = [0] * len(temperatures)
    stack = []  # Store indices, not temperatures

    for i, temp in enumerate(temperatures):
        # While stack is not empty AND current temp > temp at stack top
        while stack and temperatures[stack[-1]] < temp:
            prev_index = stack.pop()
            result[prev_index] = i - prev_index  # Days to wait

        stack.append(i)  # Always push current index

    return result

Daily Temperatures II

Problem Statement

Given an array of integers temperatures representing daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the i-th day to get a cooler temperature. If there is no future day for which this is possible, keep answer[i] == -1.

Example:

Input: temperatures = [30, 60, 90, 120, 60, 30]
Output: [-1, 4, 2, 1, 1, -1]

Monotonic Stack Solution

This is a classic monotonic stack problem. We use a decreasing monotonic stack to efficiently find the next warmer temperature.

def days_until_cooler(temps):
    result = [-1] * len(temps)
    stack = []

    for i in range(len(temps) - 1, -1, -1):
        while stack and temps[stack[-1]] >= temps[i]: #stack[-1] should be the index of coolest temperature and compare it with current temp, if the current coolest is higher than current, then pop and substitute it with current temp
            stack.pop()
        result[i] = stack[-1] - i if stack else -1
        stack.append(i) # if not going into while loop, then directly add the current index to stack for count of lower temperature

    return result

Time Complexity: O(n) - each element pushed and popped at most once
Space Complexity: O(n) - for the stack and result array

Key Insight: The stack maintains indices of days in decreasing temperature order, allowing us to efficiently find the next warmer day for each temperature.

This file will also contain:

  • More Monotonic Stack patterns
  • Expression evaluation
  • DFS using stacks
  • Backtracking applications