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); } } };