Several ways to remove invalid parentheses problem.
Starter
Return only one possible result
Method: Two pass with counter
- Scanning from left to right, ending up removing extra ‘)’
- Scanning from right to left, ending up removing extra ‘(’
|
|
Main dish (follow up)
Return all the possible results
Method 1: Two pass with DFS
- same idea as starter question: using dfs searching for valid candidate without extra ‘)’, then reverse the string and search for the second pass to remove all the extra ‘(’
- for continuous ‘)’, say “())”, always remove the first ‘)’ firstly, so “(
)
)” -> “()”: for j:[prev_j ~ i], if (s[j] == par1 && (j == prev_j || s[j-1] != par1)), remove s.charAt(j) - each recursive call, store previous i to
prev_i
to indicate that first half of string before i is valid, so no need to check again - each recursive call, store previous j to
prev_j
in order to prevent duplicate answers. e.g.:
if no prev_j stored, it’s hard to prevent the same result from two different ching branches:- “()a)a)” -> “(a)a)” -> “(aa)”
- “()a)a)” -> “()aa)” -> “(aa)”
- Time : every path generates one valid answer, if there’s k valid answer, the search will have k leaves. Since each recursive call requires O(n) time from string atenatino. O(n*m) may be fair enough to describe the time complexity, where n is length of string and m is the total nodes (numver of all the rec calls) in the ch tree
- Space: O(n*k) due to stringbuilder, k is the number of valid answer, n is the length of string
|
|
Method 2: BFS
Naive way of thinking:
For a string with n length, each char have 2 states “keep/remove”, which is 2^n states, and each state requires checkValid, which runs in O(n). Together the BFS require O(n*2^n).
Ideally, it should be O(C(n,k) + n), where k is the number of chars needs removal. To avoid generating duplicate strings, refer to this post