By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
"This pattern appears in 1 out of every 3 onsite interviews—nail it and you show clear problem-solving maturity, stack mastery, and attention to edge cases."
Before tackling Valid Parentheses, ensure you understand: 1. Stack Data Structure – LIFO (Last-In-First-Out) operations (push, pop, peek). 2. Hash Maps (Dictionaries) – O(1) lookups for key-value pairs. 3. String Iteration & Indexing – Traversing characters in a string efficiently.
push
pop
peek
([{}])
([)]
')' → '(', '}' → '{', ']' → '['
")"
""
"]"
"()))"
"()()"
"(())"
Run this exact checklist for every Valid Parentheses problem:
If string is empty → Valid (return True).
True
Initialize a Stack
Use a list (Python) or Deque (Java) for O(1) pop() and append().
Deque
pop()
append()
Define a Hash Map for Pairs
Map closing brackets to their opening counterparts: python pairs = {')': '(', '}': '{', ']': '['}
python pairs = {')': '(', '}': '{', ']': '['}
Iterate Through Each Character
For each char in the string:
char
char in pairs
stack.pop() != pairs[char]
stack.append(char)
Final Stack Check
Else → Invalid (unmatched opening brackets).
Return Result
False
Problem: Given a string s containing '()[]{}', determine if it is valid.
s
'()[]{}'
Walkthrough: 1. Edge Cases: - s = "()" → Length 2 (even) → Proceed. - s = "(" → Length 1 (odd) → Invalid. 2. Initialize: - stack = [] - pairs = {')': '(', '}': '{', ']': '['} 3. Iterate: - s = "()[]{}" - '(' → stack = ['('] - ')' → stack.pop() == '(' → Match → stack = [] - '[' → stack = ['['] - ']' → stack.pop() == '[' → Match → stack = [] - '{' → stack = ['{'] - '}' → stack.pop() == '{' → Match → stack = [] 4. Final Check: - stack is empty → Valid.
s = "()"
s = "("
stack = []
pairs = {')': '(', '}': '{', ']': '['}
s = "()[]{}"
'('
stack = ['(']
')'
stack.pop() == '('
'['
stack = ['[']
']'
stack.pop() == '['
'{'
stack = ['{']
'}'
stack.pop() == '{'
stack
Code (Python):
def isValid(s: str) -> bool: if len(s) % 2 != 0: return False stack = [] pairs = {')': '(', '}': '{', ']': '['} for char in s: if char in pairs: if not stack or stack.pop() != pairs[char]: return False else: stack.append(char) return not stack
Complexity: - Time: O(n) (single pass through the string). - Space: O(n) (worst-case stack stores all opening brackets).
Why This Works: - The stack ensures LIFO order (last opened must close first). - The hash map decouples the logic for different bracket types.
Problem: Given a string s with '()[]{}', where '' can be '(', ')', or empty, determine if it can be valid.
''
Twist: The wildcard '' adds ambiguity—we must track possible states.
Approach: 1. Track the minimum and maximum possible open brackets: - min_open: Smallest possible open brackets (treat '' as ')'). - max_open: Largest possible open brackets (treat '' as '('). 2. If max_open < 0 → Invalid (too many closing brackets). 3. If min_open > 0 → Invalid (unmatched opening brackets).
min_open
max_open
max_open < 0
min_open > 0
def checkValidString(s: str) -> bool: min_open = max_open = 0 for char in s: if char == '(': min_open += 1 max_open += 1 elif char == ')': min_open = max(min_open - 1, 0) max_open -= 1 else: # '' min_open = max(min_open - 1, 0) max_open += 1 if max_open < 0: return False return min_open == 0
Complexity: - Time: O(n) (single pass). - Space: O(1) (no stack, just counters).
Why This Works: - Greedy tracking of possible open brackets avoids backtracking. - min_open and max_open bound the solution space.
Problem: Given a string s of '(' and ')', return the minimum number of additions to make it valid.
Follow-up: Solve in O(n) time and O(1) space.
Approach: 1. Track unmatched opening and closing brackets: - open_needed: Count of ')' needed to balance '('. - close_needed: Count of '(' needed to balance ')'. 2. Iterate and update counters: - '(' → open_needed += 1 - ')' → If open_needed > 0 → open_needed -= 1 (matched), else close_needed += 1.
open_needed
close_needed
open_needed += 1
open_needed > 0
open_needed -= 1
close_needed += 1
def minAddToMakeValid(s: str) -> int: open_needed = close_needed = 0 for char in s: if char == '(': open_needed += 1 else: if open_needed > 0: open_needed -= 1 else: close_needed += 1 return open_needed + close_needed
Complexity: - Time: O(n) (single pass). - Space: O(1) (constant extra space).
Why This Works: - Greedy counting ensures we only add the minimum required brackets. - No stack needed—just two counters.
len(s) % 2 != 0
"}"
if not stack
not stack
'a'
'1'
'()'
"Alright, let’s lock this in. For Valid Parentheses, here’s your battle plan: 1. Edge Cases First: Odd length? Empty string? Handle them upfront. 2. Stack + Hash Map: Push opening brackets, pop on closing. Use a hash map to enforce correct pairs. 3. Early Termination: If you see a closing bracket with an empty stack, return False immediately. 4. Final Check: If the stack isn’t empty, there are unmatched opening brackets—return False. 5. Follow-ups: For wildcards or minimum additions, track counters instead of a stack.
Remember: This pattern tests your ability to handle LIFO logic and edge cases. Practice with '()[]{}', then try '()' and minimum additions. You’ve got this—now go crush that interview!
"("
"([)]"
"([{}])"
Now go solve it! ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.