Given a string s
containing just the characters '('
, ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
An input string is valid if:
Example 1:
Input: s = "()" Output: true
Example 2:
Input: s = "()[]{}" Output: true
Example 3:
Input: s = "(]" Output: false
Example 4:
Input: s = "([)]" Output: false
Example 5:
Input: s = "{[]}" Output: true
Constraints:
1 <= s.length <= 104
s
consists of parentheses only '()[]{}'
.The core challenge of this problem is to ensure that every opening bracket has a corresponding closing bracket and that they are correctly nested. This problem is significant in various applications such as parsing expressions in compilers, validating mathematical expressions, and ensuring the correctness of nested structures in programming languages.
Potential pitfalls include mismatched brackets, incorrect nesting, and unbalanced brackets.
To solve this problem, we can use a stack data structure. The stack helps us keep track of the opening brackets encountered, and we can match them with the corresponding closing brackets as we traverse the string.
A naive solution might involve checking each pair of brackets, but this would be inefficient and complex to implement. This approach is not optimal due to its high time complexity.
The optimized solution involves using a stack to keep track of the opening brackets. As we traverse the string, we push each opening bracket onto the stack. For each closing bracket, we check if it matches the top of the stack. If it does, we pop the stack; otherwise, the string is invalid.
import java.util.Stack;
public class ValidParentheses {
public boolean isValid(String s) {
// Initialize a stack to keep track of opening brackets
Stack<Character> stack = new Stack<>();
// Traverse each character in the string
for (char c : s.toCharArray()) {
// If the character is an opening bracket, push it onto the stack
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
} else {
// If the stack is empty or the top of the stack does not match the closing bracket, return false
if (stack.isEmpty() || !isMatchingPair(stack.pop(), c)) {
return false;
}
}
}
// If the stack is not empty, return false
return stack.isEmpty();
}
// Helper method to check if the characters are matching pairs
private boolean isMatchingPair(char open, char close) {
return (open == '(' && close == ')') ||
(open == '{' && close == '}') ||
(open == '[' && close == ']');
}
public static void main(String[] args) {
ValidParentheses vp = new ValidParentheses();
System.out.println(vp.isValid("()")); // true
System.out.println(vp.isValid("()[]{}")); // true
System.out.println(vp.isValid("(]")); // false
System.out.println(vp.isValid("([)]")); // false
System.out.println(vp.isValid("{[]}")); // true
}
}
The time complexity of this solution is O(n) because we traverse the string once. The space complexity is also O(n) due to the stack used to store the opening brackets.
Potential edge cases include:
To test the solution comprehensively, consider the following test cases:
When approaching such problems, it is essential to:
In this blog post, we discussed the problem of validating parentheses using a stack-based approach. We explored the problem definition, potential pitfalls, and provided a detailed algorithm and code implementation in Java. Understanding and solving such problems is crucial for developing strong problem-solving skills and preparing for technical interviews.
For further reading and practice, consider the following resources: