Solution: Remove Invalid Parentheses
Let’s solve the Remove Invalid Parentheses problem using the Backtracking pattern.
We'll cover the following
Statement
You are given a string, s
, that contains:
Lowercase English letters
Opening
'('
and closing')'
parentheses
A string is considered valid if:
All opening parentheses
'('
are closed properly by a matching')'
.The parentheses are in the correct order and nesting.
Letters can appear anywhere and do not affect validity.
Return all possible valid strings that can be formed by removing the minimum number of invalid parentheses. The answer must be a list of unique strings, in any order.
Constraints:
s.length
s
consists of lowercase English letters and parentheses'('
and')'
.There will be at most
20
parentheses ins
.
Solution
The algorithm aims to generate all possible valid strings by removing the minimum number of invalid parentheses. It starts with a preprocessing step to determine how many opening and closing parentheses need to be removed. As it scans the string, it increments a counter for each opening parenthesis. For each closing parenthesis, it tries to match it with an opening one. If no match is found, it marks the closing parenthesis as unmatched. This ensures the algorithm knows the minimum number of each type of parenthesis to remove.
Once the number of invalid parentheses is known, the algorithm uses recursive backtracking to explore all valid combinations. It processes the string one character at a time and considers several choices:
If the character is an opening parenthesis
(
, the algorithm considers two choices: skip it to reduce the number of unmatched openings, or add it to the expression and increase the open count.If it’s a closing parenthesis
)
, it can be skipped to reduce unmatched closings, or added to the expression—but only if more opening parentheses are already added, to keep the expression balanced.If it’s a non-parenthesis character, it is always added to the current expression.
The recursion continues until the end of the string is reached. At that point, if the number of opening and closing parentheses is equal (i.e., the expression is balanced) and no more removals are needed, the expression is added to a result set to ensure uniqueness. After exploring all possibilities, the algorithm returns all unique valid expressions as a list.
The steps of the algorithm are as follows:
Count the minimum invalid parentheses to remove:
Initialize two counters,
leftToRemove
(Number of extra'('
to remove) andrightToRemove
(Number of extra')'
to remove).Iterate through the string:
If the character is
'('
, incrementleftToRemove
.If the character is
')'
:If
leftToRemove > 0
, a matching'('
exists, so decrementleftToRemove
.Else, increment
rightToRemove
(unmatched right parenthesis).
We define a recursive helper function,
backtrack(index, openCount, closeCount, path, leftRemain, rightRemain)
to explore all valid combinations of the input string.index
is the current position in the string.openCount
andcloseCount
track the number of '(' and ')' in the current path to maintain balance.path
holds the built string so far.leftRemain
andrightRemain
indicate how many '(' and ')' can still be removed to form a valid expression.
When the end of the string is reached (i.e.,
index == len(s)
), check if no removals remain (leftRemain == 0
andrightRemain == 0
) and the parentheses are balanced (open_count == close_count
). If so, add the current path to the result set.Recursive case: At each character
char = s[index]
:
If
char == '('
:Option to remove it (if
leftRemain > 0
):Recurse without adding
'('
, decrementingleftRemain
.
Option to keep it:
Recurse adding
'('
to path, incrementingopenCount
.
If
char == ')'
:Option to remove it (if
rightRemain > 0
):Recurse without adding
')'
, decrementingrightRemain
.
Option to keep it:
Only if
closeCount < openCount
(to ensure balance).Recurse adding
')'
, incrementingcloseCount
.
If
char
is not a parenthesis:Always keep it and recurse with the character added to
path
.
3. Call backtrack(0, 0, 0, '', leftToRemove, rightToRemove)
to begin from index 0 and an empty path.
4. Convert the result set result
to a list and return it.
Let’s look at the following illustration to get a better understanding of the solution:
Level up your interview prep. Join Educative to access 70+ hands-on prep courses.