Skip to main content
Easy Stack High frequency

Valid Parentheses

Open on LeetCode

Approach Summary

Push open brackets. On close bracket, check if top of stack is the matching open bracket.

Full Solution & Approach

Bracket matching is inherently stack-shaped: the most recently opened bracket must be closed first (LIFO). Iterate through the string. For every opening bracket — ( [ or { — push it onto the stack. For every closing bracket, the top of the stack must be its matching opener; if the stack is empty or the top does not match, the string is invalid. If it matches, pop. At the end the string is valid only if the stack is empty — leftover openers mean something was never closed. Using a dictionary that maps each closing bracket to its opener turns the match check into a single lookup. This runs in one pass with O(1) operations per character, so O(n) total.

Single pass with each bracket pushed once and popped at most once — O(n) time. The stack grows to at most n for a string of only openers — O(n) space.

Solution Code

Solution

def is_valid(s: str) -> bool:
    pairs = {')': '(', ']': '[', '}': '{'}
    stack = []
    for ch in s:
        if ch in pairs:
            if not stack or stack[-1] != pairs[ch]:
                return False
            stack.pop()
        else:
            stack.append(ch)
    return not stack

Edge Cases to Watch

  • Empty string — valid (return true)
  • Starts with a closing bracket — the stack is empty, immediately false
  • Ends with an opener — the stack is non-empty at the end, false
  • Mismatched nesting like "([)]" — the top-of-stack check catches it

How to Recognize This Pattern

  • Bracket matching
  • Nested structure validation

Complexity Analysis

Time Complexity

O(n)

Space Complexity

O(n)

Tags

String Stack

This site is free. If these guides are helping your prep, consider buying me a coffee. ☕

Support →
Buy me a coffee