Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    EasyStack

    Valid Parentheses

    Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    An input string is valid if:

    1. Open brackets must be closed by the same type of bracket.
    2. Open brackets must be closed in the correct order.
    3. Every close bracket has a corresponding open bracket of the same type.

    Example 1

    Input: s = "()"

    Output: true

    Example 2

    Input: s = "()[]{}"

    Output: true

    Example 3

    Input: s = "(]"

    Output: false

    Constraints

    • 1 <= s.length <= 10^4
    • s consists of parentheses only '()[]{}'.
    View original on LeetCode ↗

    Brute Force (Repeated Removal)

    Time O(n²)Space O(n)

    A valid string can always be fully reduced by repeatedly deleting any adjacent matching pair — (), [], or {} — until nothing removable is left. If what remains is empty, the string was valid.

    class Solution:
    def isValid(self, s: str) -> bool:
    prev_len = -1
    while len(s) != prev_len:
    prev_len = len(s)
    s = s.replace('()', '').replace('[]', '').replace('{}', '')
    return len(s) == 0

    Each pass scans the string in O(n), and in the worst case (deeply nested brackets like ((((...))))) it takes O(n) passes to fully collapse — O(n²) total, plus the wasted work of rebuilding a new string on every pass.

    Stack

    OptimalTime O(n)Space O(n)

    Scan left to right with a stack. Every opening bracket gets pushed. Every closing bracket must match whatever is currently on top of the stack — that’s exactly the “most recently opened, must close first” rule, which is what a stack gives you for free.

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

    Watch the closer-versus-stack-top comparison: a closer that does not match the top stops the scan immediately.

    Input

    ([{})]

    Comparison

    closer—
    needs
    opener—
    vs top
    stack top—

    Stack

    empty

    Verdict

    in progress
    1 / 6
    currentseencomparing
    invalid

    Scan left to right. Openers wait on the stack; each closer must match whatever is on top.

    If a closing bracket ever finds a mismatched (or missing) top of stack, we return False immediately — that’s what catches cases like "(]". Complexity: each character is pushed and popped at most once → O(n) time, O(n) space for the stack in the worst case (all openers).

    More Stack practice