Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- 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
Example 4:
Input: s = "([])"
Output: true
Example 5:
Input: s = "([)]"
Output: false
Constraints:
1 <= s.length <= 10^4sconsists of parentheses only'()[]{}'.
This solution uses the Stack data structure with unified switch-case pattern:
- Stack (LIFO) Strategy: Use ArrayDeque as a stack to track opening brackets in Last-In-First-Out order
- Unified Switch Pattern: Handle both opening and closing brackets in a single switch statement for better performance
- Enhanced For Loop: Use
toCharArray()to avoid multiplecharAt()calls and improve efficiency - Immediate Validation: Check stack conditions and bracket matching in one operation for closing brackets
- Final Stack Check: Ensure all opening brackets have been matched by checking if stack is empty
- Initialize an ArrayDeque as a stack to store opening brackets
- Iterate through each character in the string using enhanced for loop
- For opening brackets
(,{,[: push them onto the stack - For closing brackets
),},]:- Check if stack is empty (no matching opening bracket) → return false
- Pop the top element and verify it matches the current closing bracket → return false if mismatch
- After processing all characters, return true if stack is empty (all brackets matched)
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new ArrayDeque<>();
for (char c : s.toCharArray()) { // Enhanced for loop for better performance
switch (c) {
case '(': // Opening brackets
case '{':
case '[':
stack.push(c);
break;
case ')': // Closing brackets with immediate validation
if (stack.isEmpty() || stack.pop() != '(') return false;
break;
case '}':
if (stack.isEmpty() || stack.pop() != '{') return false;
break;
case ']':
if (stack.isEmpty() || stack.pop() != '[') return false;
break;
}
}
return stack.isEmpty(); // All brackets must be matched
}
}- Time Complexity: O(n) where n is the length of the input string
- Space Complexity: O(n) in the worst case when all characters are opening brackets
- Runtime: 2 ms - Beats 96.61% of Java submissions
- Memory Usage: 41.75 MB - Beats 69.96% of Java submissions
- ArrayDeque over Stack: Using modern
ArrayDequeinstead of legacyStackclass for better performance (no synchronization overhead) - Unified Switch Statement: Single switch handles all bracket types, reducing branching and improving readability
- Enhanced For Loop: Using
toCharArray()eliminates repeatedcharAt()method calls - Immediate Return Strategy: Early exit on first invalid condition prevents unnecessary processing
- Combined Condition Checking: Stack emptiness and bracket matching verified in single expressions
- LIFO Nature: Last opened bracket must be first to close - exactly how stack works
- Nested Structure: Brackets can be nested, and stack naturally handles this hierarchy
- Order Validation: Stack ensures correct opening/closing order automatically
- Memory Efficiency: Only stores unmatched opening brackets
- Problem: 20. Valid Parentheses
- Solution: My Submission)
Stack String Data Structure Bracket Matching LIFO ArrayDeque