Given a parentheses string s containing only the characters '(' and ')'. A parentheses string is balanced if:
'(' must have a corresponding two consecutive right parenthesis '))'.'(' must go before the corresponding two consecutive right parenthesis '))'.In other words, we treat '(' as an opening parenthesis and '))' as a closing parenthesis.
"())", "())(())))" and "(())())))" are balanced, ")()", "()))" and "(()))" are not balanced.You can insert the characters '(' and ')' at any position of the string to balance it if needed.
Return the minimum number of insertions needed to make s balanced.
Example 1:
Input: s = "(()))"
Output: 1
Explanation: The second '(' has two matching '))', but the first '(' has only ')' matching. We need to add one more ')' at the end of the string to be "(())))" which is balanced.
Example 2:
Input: s = "())" Output: 0 Explanation: The string is already balanced.
Example 3:
Input: s = "))())("
Output: 3
Explanation: Add '(' to match the first '))', Add '))' to match the last '('.
Constraints:
1 <= s.length <= 105s consists of '(' and ')' 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:
The brute force approach to balancing a parentheses string is like trying every possible combination of inserting open and close parentheses until we find one that works. It involves exploring every possible alteration to the string and verifying its balance.
Here's how the algorithm would work step-by-step:
def minimum_insertions_brute_force(parentheses_string):
min_insertions = float('inf')
queue = [(parentheses_string, 0)]
while queue:
current_string, insertions = queue.pop(0)
# Check if the current string is balanced
if is_balanced(current_string):
min_insertions = min(min_insertions, insertions)
continue
if insertions >= min_insertions:
continue
# Limit search depth to avoid infinite loops
if insertions > len(parentheses_string):
continue
for index in range(len(current_string) + 1):
# Try inserting an open parenthesis
new_string_open = current_string[:index] + '(' + current_string[index:]
queue.append((new_string_open, insertions + 1))
# Try inserting a close parenthesis
new_string_close = current_string[:index] + ')' + current_string[index:]
queue.append((new_string_close, insertions + 1))
if min_insertions == float('inf'):
return -1
return min_insertions
def is_balanced(parentheses_string):
balance = 0
for char in parentheses_string:
if char == '(': balance += 1
elif char == ')': balance -= 1
#Early exit if unbalanced
if balance < 0: return False
#After processing the entire string, it is balanced if the balance is zero
return balance == 0The key is to keep track of how many open parentheses we need to close. We also need to recognize that two closing parentheses are always required for every open parenthesis. We address imbalances as they appear, ensuring that we only add insertions when absolutely necessary.
Here's how the algorithm would work step-by-step:
def min_insertions(parenthesis_string):
needed_closing_parentheses = 0
insertions = 0
for character in parenthesis_string:
if character == '(':
needed_closing_parentheses += 2
elif character == ')':
# We need to insert an opening parenthesis.
if needed_closing_parentheses == 0:
insertions += 1
needed_closing_parentheses = 1
# Reduce the need for a closing parenthesis.
needed_closing_parentheses -= 1
# Any remaining needed closing parenthesis at the end need insertions.
insertions += needed_closing_parentheses
return insertions| Case | How to Handle |
|---|---|
| Null or empty input string | Return 0 immediately since an empty string is already balanced. |
| Input string with only opening parentheses | The number of insertions needed is twice the number of opening parentheses. |
| Input string with only closing parentheses | The number of insertions needed is the number of closing parentheses. |
| String with deeply nested parentheses | Stack-based or counter-based approaches must handle large nesting depths without overflow. |
| String with unbalanced parentheses at the end | The algorithm should correctly account for any remaining unmatched parentheses after processing the entire string. |
| Maximum length string with highly unbalanced parentheses | The solution's time and space complexity should be considered to ensure it scales efficiently. |
| Input string with mixed single and double closing parenthesis | The solution should be able to differentiate '(' from ')' and ')))'. |
| String starts with single close parenthesis | Add an open parenthesis to the total insertion and consider the string '(...' for future balancing. |