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: true
Example 5:
Input: s = "([)]"
Output: false
Constraints:
1 <= s.length <= 104
s
consists of parentheses only '()[]{}'
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
With the brute force method, we are trying to find if a string of parentheses is valid by generating and testing all combinations. We will explore every possible way the parentheses could be matched.
Here's how the algorithm would work step-by-step:
def is_valid_parentheses_brute_force(input_string):
string_length = len(input_string)
# If the length is odd, it cannot be valid
if string_length % 2 != 0:
return False
possible_arrangements = generate_arrangements(input_string)
for arrangement in possible_arrangements:
if is_valid_arrangement(arrangement):
return True
return False
def generate_arrangements(input_string):
if not input_string:
return [""]
arrangements = []
for i in range(len(input_string)):
rest_of_string = input_string[:i] + input_string[i+1:]
for sub_arrangement in generate_arrangements(rest_of_string):
arrangements.append(input_string[i] + sub_arrangement)
return arrangements
def is_valid_arrangement(arrangement):
stack = []
parentheses_map = {")": "(", "}": "{", "]": "["}
for character in arrangement:
if character in ['(', '{', '[']:
stack.append(character)
elif character in [')', '}', ']']:
if not stack:
return False
top_element = stack.pop()
# Check for matching parenthesis types
if parentheses_map[character] != top_element:
return False
#The stack should be empty at the end
return not stack
The best way to solve this is to use a mental model of cancelling things out. Think of opening parentheses as something that needs to be closed later. We use a mechanism to keep track of what needs to be closed.
Here's how the algorithm would work step-by-step:
def is_valid(string_of_parentheses: str) -> bool:
stack_of_open_parentheses = []
parentheses_map = {
')': '(',
'}': '{',
']': '['
}
for character in string_of_parentheses:
if character in parentheses_map.values():
stack_of_open_parentheses.append(character)
elif character in parentheses_map:
# Need to check if there are any open parentheses
if not stack_of_open_parentheses:
return False
# The top of the stack should match
top_element = stack_of_open_parentheses.pop()
if parentheses_map[character] != top_element:
return False
# At the end, the stack should be empty
# to ensure proper opening and closing
return not stack_of_open_parentheses
Case | How to Handle |
---|---|
Empty string | Return true, as an empty string is considered valid. |
Null input | Return true, or throw an IllegalArgumentException depending on the specified requirements. |
String with only open brackets (e.g., '{{{') | Return false, as there are unmatched open brackets. |
String with only closing brackets (e.g., '}}}') | Return false, as there are no corresponding open brackets. |
String with mismatched brackets (e.g., '({[}])') | Return false, because the brackets are not closed in the correct order. |
String with mixed valid and invalid sequences (e.g., '(){}[](') | Return false, as the whole string must be validated. |
Very long string, potentially exceeding stack size if using recursion. | Iterative solution using a stack avoids stack overflow issues for large inputs. |
String containing characters other than brackets | Return false, or ignore the non-bracket characters, based on the specific requirements, while ensuring that the brackets are valid. |