1
# Runtime: 96 ms (Top 83.6%) | Memory: 18.67 MB (Top 9.9%)
2

3

4
class Solution:
5
def removeInvalidParentheses(self, s: str) -> List[str]:
6
## RC ##
7
## APPROACH : BACK-TRACKING ##
8
## Similar to Leetcode 32. Longest Valid Parentheses ##
9
## LOGIC ##
10
# 1. use stack to find invalid left and right braces.
11
# 2. if its close brace at index i , you can remove it directly to make it valid and also you can also remove any of the close braces before that i.e in the range [0,i-1]
12
# 3. similarly for open brace, left over at index i, you can remove it or any other open brace after that i.e [i+1, end]
13
# 4. if left over braces are more than 1 say 2 close braces here, you need to make combinations of all 2 braces before that index and find valid parentheses.
14
# 5. so, we count left and right invalid braces and do backtracking removing them
15

16
## TIME COMPLEXITY : O(2^N) ## (each brace has 2 options: exits or to be removed)
17
## SPACE COMPLEXITY : O(N) ##
18

19
def isValid(s):
20
stack = []
21
for i in range(len(s)):
22
if s[i] == "(":
23
stack.append((i, "("))
24
elif s[i] == ")":
25
if stack and stack[-1][1] == "(":
26
stack.pop()
27
else:
28
stack.append((i, ")")) # pushing invalid close braces also
29
return len(stack) == 0, stack
30

31
def dfs(s, left, right):
32
visited.add(s)
33
if left == 0 and right == 0 and isValid(s)[0]:
34
res.append(s)
35
for i, ch in enumerate(s):
36
if ch != "(" and ch != ")":
37
continue # if it is any other char ignore.
38
if (ch == "(" and left == 0) or (ch == ")" and right == 0):
39
continue # if left == 0 then removing '(' will only cause imbalance. Hence, skip.
40
if s[:i] + s[i + 1 :] not in visited:
41
dfs(s[:i] + s[i + 1 :], left - (ch == "("), right - (ch == ")"))
42

43
stack = isValid(s)[1]
44
lc = sum([1 for val in stack if val[1] == "("]) # num of left braces
45
rc = len(stack) - lc
46

47
res, visited = [], set()
48
dfs(s, lc, rc)
49
return res

0

WPM •0 •0

100%

ACC •0 •0

0s

TIME •0