Given a string s
consisting 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 <= 10^5
s[i]
is either '('
, ')'
, or lowercase English letter.One straightforward, albeit inefficient, approach is to generate all possible subsequences of the input string s
and check each subsequence for validity. We would keep track of the longest valid subsequence found so far. This involves exploring all possible combinations of including or excluding each character, leading to exponential time complexity.
Algorithm:
Validity Check:
A string is a valid parentheses string if:
def is_valid(s):
balance = 0
for char in s:
if char == '(':
balance += 1
elif char == ')':
balance -= 1
if balance < 0:
return False
return balance == 0
def remove_invalid_parentheses_brute_force(s):
import itertools
all_subsequences = []
for i in range(len(s) + 1):
for subset in itertools.combinations(s, i):
all_subsequences.append("".join(subset))
valid_subsequences = [sub for sub in all_subsequences if is_valid(sub)]
if not valid_subsequences:
return ""
return max(valid_subsequences, key=len)
#Example usage:
s = "lee(t(c)o)de)"
result = remove_invalid_parentheses_brute_force(s)
print(result)
A more efficient approach involves using a stack (or a counter) to keep track of parentheses balance and performing two passes through the string.
Algorithm:
balance
counter. Increment for '(' and decrement for ')'.balance
becomes negative, it means there are more closing parentheses than opening parentheses. Mark the current ')' for removal. Reset balance to 0.balance
counter. Increment for ')' and decrement for '('.balance
becomes negative, it means there are more opening parentheses than closing parentheses. Mark the current '(' for removal. Reset balance to 0.def remove_invalid_parentheses(s):
s_list = list(s)
def remove_invalid(s_list, char1, char2):
balance = 0
for i in range(len(s_list)):
if s_list[i] == char1:
balance += 1
elif s_list[i] == char2:
balance -= 1
if balance < 0:
s_list[i] = ""
balance = 0
return s_list
# First pass: Remove extra ')'
s_list = remove_invalid(s_list, '(', ')')
# Reverse the string and remove extra '('
s_list.reverse()
s_list = remove_invalid(s_list, ')', '(')
s_list.reverse()
return "".join(s_list)
#Example usage:
s = "lee(t(c)o)de)"
result = remove_invalid_parentheses(s)
print(result)
s = "a)b(c)d"
result = remove_invalid_parentheses(s)
print(result)
s = "))(("
result = remove_invalid_parentheses(s)
print(result)