class Solution {
public:
unordered_set<string> res; // DFS may produce dup result, use set to filter.
vector<string> removeInvalidParentheses(string s) {
// Calculate rmL and rmR for the numbers of () we need to remove.
int rmL = 0, rmR = 0;
for (auto c : s) {
if (c == '(') rmL++;
else if (c == ')') {
if (rmL > 0) rmL--;
else rmR++;
}
}
dfs(s, "", 0, rmL, rmR, 0);
return vector<string>(res.begin(), res.end());
}
void dfs(const string& s, string path, int cur, int rmL, int rmR, int open) {
// Ignore non()
while (cur < s.length() && s[cur] != '(' && s[cur] != ')') {
path.push_back(s[cur]);
cur++;
}
if (cur == s.length()) {
if (open == 0 && rmL == 0 && rmR == 0) {
res.insert(path);
}
return;
}
if (s[cur] == '(') {
if (rmL > 0) // we can remove (, and we remove.
dfs(s, path, cur+1, rmL-1, rmR, open);
dfs(s, path + "(", cur+1, rmL, rmR, open+1); // we keep this (.
}
else if (s[cur] == ')') {
if (rmR > 0) // we can remove ), and we remove.
dfs(s, path, cur+1, rmL, rmR-1, open);
if (open > 0) // we have ( to match, keep it.
dfs(s, path+")", cur+1, rmL, rmR, open-1);
}
}
};