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:
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:
class Solution:
def minRemoveToMakeValid(self, s: str) -> str:
stack = []
indices_to_remove = set()
for i, char in enumerate(s):
if char == '(':
stack.append(i)
elif char == ')':
if stack:
stack.pop()
else:
indices_to_remove.add(i)
# Remaining indices in the stack are unmatched '('
indices_to_remove.update(stack)
result = []
for i, char in enumerate(s):
if i not in indices_to_remove:
result.append(char)
return "".join(result)
The naive approach would be to generate all possible subsequences of the string s
and check each one for validity. Then return the valid string with the longest length. This approach is not efficient since the number of subsequences of a string of length n
is 2^n. This results in exponential time complexity, which is not practical for larger input sizes.
The optimal approach involves using a stack to keep track of the indices of open parentheses. When a closing parenthesis is encountered, check if there's a corresponding open parenthesis in the stack. If there is, pop the open parenthesis from the stack. If not, or if there are unmatched open parentheses in the stack after processing the entire string, mark those parentheses for removal. Finally, construct a new string excluding those marked for removal.
Consider the input string s = "lee(t(c)o)de)"
.
The time complexity of the provided solution is O(n), where n is the length of the input string s
. This is because the algorithm iterates through the string once to identify the indices to remove and then iterates through the string again to construct the result. Both iterations take O(n) time, so the overall time complexity is O(n).
The space complexity of the provided solution is O(n) in the worst case. This is because the stack
can grow up to the number of open parentheses in the string s
, and indices_to_remove
can also store up to n
indices in the worst case (e.g., "((((((("). Additionally, the result
list can grow up to n
characters. Thus, the overall space complexity is O(n).
s
is empty, the function should return an empty string. The provided code handles this case correctly since the loops will not execute, and the initial empty string will be returned.s
contains no parentheses, it is already a valid parentheses string, so the function should return the original string. The provided code handles this case correctly because the stack
and indices_to_remove
will remain empty, and the result will be the same as the input string.s
contains only open parentheses, all the indices should be removed. The provided code handles this case correctly because after the loop, the stack
will contain all the indices, and they will be added to indices_to_remove
.s
contains only close parentheses, all the indices should be removed. The provided code handles this case correctly because the stack
will always be empty, and the index of each close parenthesis will be added to indices_to_remove
.