A parentheses string is valid if and only if:
AB
(A
concatenated with B
), where A
and B
are valid strings, or(A)
, where A
is a valid string.You are given a parentheses string s
. In one move, you can insert a parenthesis at any position of the string.
s = "()))"
, you can insert an opening parenthesis to be "(()))"
or a closing parenthesis to be "())))"
.Return the minimum number of moves required to make s
valid.
Example 1:
Input: s = "())" Output: 1
Example 2:
Input: s = "(((" Output: 3
Constraints:
1 <= s.length <= 1000
s[i]
is either '('
or ')'
.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:
The goal is to find the fewest parentheses we must add to a string of parentheses to make it balanced. The brute force way involves trying all combinations of adding parentheses until a valid arrangement is found, then selecting the best one.
Here's how the algorithm would work step-by-step:
def minimum_add_to_make_parentheses_valid_brute_force(parentheses_string):
minimum_additions_needed = float('inf')
queue = [(parentheses_string, 0)]
while queue:
current_string, additions_made = queue.pop(0)
if is_valid(current_string):
# We only want to keep track of the smallest additions
minimum_additions_needed = min(minimum_additions_needed, additions_made)
continue
if additions_made >= minimum_additions_needed:
continue
# Try adding a left parenthesis at each position
for index in range(len(current_string) + 1):
new_string = current_string[:index] + '(' + current_string[index:]
queue.append((new_string, additions_made + 1))
# Limit the size of the queue
if len(queue) > 1000:
break
# Try adding a right parenthesis at each position
for index in range(len(current_string) + 1):
new_string = current_string[:index] + ')' + current_string[index:]
queue.append((new_string, additions_made + 1))
# Limit the size of the queue
if len(queue) > 1000:
break
return minimum_additions_needed
def is_valid(parentheses_string):
balance = 0
for char in parentheses_string:
if char == '(':
balance += 1
else:
balance -= 1
# String is invalid if the balance ever drops below 0
if balance < 0:
return False
# The string is valid if the balance is 0 at the end
return balance == 0
We need to figure out the fewest parentheses we need to add to a string so that every opening parenthesis has a matching closing one, and vice-versa. The key is to keep track of how many open parentheses are currently unmatched.
Here's how the algorithm would work step-by-step:
def minAddToMakeValid(input_string):
unmatched_open_parenthesis = 0
needed_parenthesis_count = 0
for character in input_string:
if character == '(':
unmatched_open_parenthesis += 1
elif character == ')':
# If there is no open parenthesis
# to match the current closing one.
if unmatched_open_parenthesis == 0:
needed_parenthesis_count += 1
else:
# Found matching parenthesis.
unmatched_open_parenthesis -= 1
# Add any remaining unmatched open
# parenthesis to the result.
needed_parenthesis_count += unmatched_open_parenthesis
return needed_parenthesis_count
Case | How to Handle |
---|---|
Empty string input | Return 0, as an empty string is already a valid parentheses string. |
String with only opening parentheses: '(((' | Count the number of unmatched opening parentheses and return that count. |
String with only closing parentheses: ')))' | Count the number of unmatched closing parentheses and return that count. |
String with alternating parentheses: '()()()' | Return 0, as the string is already valid. |
String with mixed but invalid parentheses: '())(' | Keep track of the balance; unmatched closing parens add to answer and unmatched opening parens at the end also added. |
Very long string consisting only of '(' to test for stack overflow | Iterative approach using a counter avoids stack overflow issues. |
String with deeply nested valid parentheses followed by invalid close parentheses: '((((()))))' | The counter-based approach handles the nesting and correctly counts remaining unmatched close parenthesis after the valid sequence. |
String with a mix of extremely unbalanced open and close parenthesis '((((((())))))((' | The algorithm correctly handles accumulation of unmatched open and close parentheses. |