Given a string s of '('
, ')'
and lowercase English characters.
Your task is to remove the minimum number of parentheses ( '('
or ')'
, in any positions ) so that the resulting parentheses string is valid and return any valid string.
Formally, 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.Example 1:
Input: s = "lee(t(c)o)de)" Output: "lee(t(c)o)de" Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted.
Example 2:
Input: s = "a)b(c)d" Output: "ab(c)d"
Example 3:
Input: s = "))((" Output: "" Explanation: An empty string is also valid.
Constraints:
1 <= s.length <= 105
s[i]
is either '('
, ')'
, or lowercase English letter.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 method for making parentheses valid involves trying every possible combination of removals. We explore all possibilities by removing different parentheses one by one until we find a valid combination.
Here's how the algorithm would work step-by-step:
def minimum_remove_to_make_valid_parentheses_brute_force(input_string):
longest_valid_string = ""
# Generate all possible substrings by removing characters
for i in range(1 << len(input_string)):
current_string = ""
indices_to_keep = []
for j in range(len(input_string)):
if (i >> j) & 1:
current_string += input_string[j]
indices_to_keep.append(j)
# Check if the current string is valid
if is_valid(current_string):
# We want to keep the longest one found so far
if len(current_string) > len(longest_valid_string):
longest_valid_string = current_string
return longest_valid_string
def is_valid(current_string):
balance = 0
for char in current_string:
if char == '(':
balance += 1
elif char == ')':
balance -= 1
# If balance becomes negative, it's invalid
if balance < 0:
return False
# String is valid if balance is 0
return balance == 0
The key idea is to scan the input once to identify and mark the parentheses that need to be removed to make the string valid. We use a counter to keep track of open parentheses and then remove the extra ones that don't have a match.
Here's how the algorithm would work step-by-step:
def min_remove_to_make_valid(input_string: str) -> str:
string_length = len(input_string)
indices_to_remove = [False] * string_length
open_parenthesis_count = 0
for index in range(string_length):
if input_string[index] == '(':
open_parenthesis_count += 1
elif input_string[index] == ')':
if open_parenthesis_count > 0:
open_parenthesis_count -= 1
else:
# Mark extra closing parenthesis for removal.
indices_to_remove[index] = True
closing_parenthesis_count = 0
for index in range(string_length - 1, -1, -1):
if input_string[index] == ')':
closing_parenthesis_count += 1
elif input_string[index] == '(':
if closing_parenthesis_count > 0:
closing_parenthesis_count -= 1
else:
# Mark extra opening parenthesis for removal.
indices_to_remove[index] = True
result = ''
for index in range(string_length):
if not indices_to_remove[index]:
result += input_string[index]
return result
Case | How to Handle |
---|---|
Empty string input | Return the empty string itself, as it's already a valid parentheses string of length 0. |
String with only opening parentheses | Remove all opening parentheses to get an empty valid string. |
String with only closing parentheses | Remove all closing parentheses to get an empty valid string. |
String with balanced parentheses and other characters | The solution correctly identifies and preserves the balanced parentheses and other characters. |
String with nested unbalanced parentheses | The algorithm efficiently removes only the necessary unbalanced parentheses. |
String with a large number of characters | The solution should have a time complexity of at most O(n) to handle large inputs efficiently, where n is the length of the string. |
String with deeply nested parentheses that could potentially cause stack overflow issues if recursion were used inappropriately | Iterative solutions should be preferred to avoid potential stack overflow for deeply nested parentheses; Stack based solution should bound memory appropriately. |
String with mixed valid and invalid parentheses scattered throughout | The solution should maintain the relative order of valid parentheses and non-parenthesis characters while removing the minimum number of invalid parentheses. |