150NeetCode 150

21.Valid Parentheses

EasyBlind 75Stack ยท 1/7

Problem

Given a string s containing only the characters '(', ')', '{', '}', '[' and ']', decide whether it is valid:

  1. Every open bracket is closed by a bracket of the same type.
  2. Open brackets are closed in the correct order (the most recently opened must close first).
  3. Every close bracket has a matching open bracket.

Examples

Input:  s = "()[]{}"
Output: true
Input:  s = "([)]"
Output: false
Explanation: '[' is opened after '(' so it must close first, but ')' arrives first.
Input:  s = "{[]}"
Output: true
Explanation: Brackets are properly nested.

Constraints

  • 1 <= s.length <= 10^4
  • s consists of parentheses only: '()[]{}'.

๐Ÿ’ก Key Insight

"The most recently opened bracket must be closed first" is exactly last-in, first-out. Push each opening bracket onto a stack; each closing bracket must match the top of the stack. The string is valid iff every closer matches and the stack is empty at the end.

Brute Force (Repeated Removal)

TimeO(nยฒ)SpaceO(n)

Intuition

In any valid string, at least one adjacent pair "()", "[]" or "{}" exists (the innermost pair). Removing it leaves another valid string. So keep deleting adjacent pairs until nothing changes; the string was valid iff it becomes empty.

Algorithm

  1. Repeat:
    • Replace every "()", "[]", "{}" with "".
    • If the length did not change, stop.
  2. Return s.isEmpty().

Visualization

"{[()]}"  โ†’ remove "()" โ†’ "{[]}"
"{[]}"    โ†’ remove "[]" โ†’ "{}"
"{}"      โ†’ remove "{}" โ†’ ""      โ†’ true

"([)]"    โ†’ no adjacent pair      โ†’ stuck, not empty โ†’ false

Code

java
class Solution {
    public boolean isValid(String s) {
        int before;
        do {
            before = s.length();
            // strip every innermost matching pair
            s = s.replace("()", "").replace("[]", "").replace("{}", "");
        } while (s.length() != before);
        return s.isEmpty();
    }
}

Complexity

  • Time: O(nยฒ) โ€” up to n / 2 rounds, each rebuilding a string of length up to n.
  • Space: O(n) โ€” new strings are created on every replace.

Complexity Comparison

Approach Time Space
Brute Force (repeated removal) O(nยฒ) O(n)
Stack + Map O(n) O(n)
Stack of Expected Closers O(n) O(n)

Common Pitfalls

  • Counting brackets per type โ€” "([)]" has balanced counts but invalid order; you need a stack.
  • Popping from an empty stack on a leading closer like ")(" โ€” check emptiness first.
  • Returning true at the end without checking the stack is empty โ€” "((" would wrongly pass.
  • Comparing two Character objects with ==/!= โ€” that compares references; unbox one side to char first.
  • Using java.util.Stack โ€” it works but is synchronized and slower; prefer ArrayDeque or a plain array.