301. Remove Invalid Parentheses
Last updated
Was this helpful?
Last updated
Was this helpful?
Was this helpful?
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses (
and )
.
Example 1:
Input: "()())()"
Output: ["()()()", "(())()"]
Example 2:
Input: "(a)())()"
Output: ["(a)()()", "(a())()"]
Example 3:
Input: ")("
Output: [""]
// BFS
bool isValid(const string& str) {
int cnt = 0;
for (char ch : str) {
if (ch == '(') ++cnt;
else if (ch == ')' && --cnt < 0) return false;
}
return cnt == 0;
}
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
unordered_set<string> visited({s});
queue<string> q({s});
bool found = false;
while (!q.empty()) {
string t = q.front(); q.pop();
if (isValid(t)) {
res.push_back(t);
found = true;
}
if (found) continue;
// Remove one char from the t string
for (int i = 0; i < t.length(); ++i) {
if (t[i] != '(' && t[i] != ')') continue;
string new_str = t.substr(0, i) + t.substr(i + 1);
if (!visited.count(new_str)) {
q.push(new_str);
visited.insert(new_str);
}
}
}
return res;
}
// Recursion
bool isValid(const string& s) {
int cnt = 0;
for (int i = 0; i < s.length(); ++i) {
if (s[i] == '(') ++cnt;
else if (s[i] == ')' && --cnt < 0) return false;
}
return cnt == 0;
}
void helper(string s, int start, int cnt1, int cnt2, vector<string>& res) {
if (cnt1 == 0 && cnt2 == 0) {
if (isValid(s)) res.push_back(s);
return;
}
for (int i = start; i < s.length(); ++i) {
if (i != start && s[i] == s[i - 1]) continue;
if (cnt1 > 0 && s[i] == '(') {
helper(s.substr(0, i) + s.substr(i + 1), i, cnt1 - 1, cnt2, res);
}
if (cnt2 > 0 && s[i] == ')') {
helper(s.substr(0, i) + s.substr(i + 1), i, cnt1, cnt2 - 1, res);
}
}
}
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
int cnt1 = 0, cnt2 = 0; // cnt1: surplus number of (, cnt2: surplus number of )
// Calculate cnt1 and cnt2
for (char ch : s) {
cnt1 += (ch == '(');
if (cnt1 == 0) cnt2 += (ch == ')');
else cnt1 -= (ch == ')');
}
helper(s, 0, cnt1, cnt2, res);
return res;
}
// Optimized Recursion
void helper(string s, int start, int last_del, const string& p, vector<string>& res) {
int cnt = 0;
for (int i = start; i < s.length(); ++i) {
if (s[i] == p[0]) ++cnt;
else if (s[i] == p[1]) --cnt;
if (cnt >= 0) continue;
// Delete extra p[1]
for (int j = last_del; j <= i; ++j) {
if (s[j] == p[1] && (j == last_del || (s[j] != s[j - 1]))) {
helper(s.substr(0, j) + s.substr(j + 1), i, j, p, res);
}
}
return; // if the program runs to here, no need to reverse to delete extra p[0]
}
// Delete extra p[0]
string rev = string(s.rbegin(), s.rend());
if (p[0] == '(') helper(rev, 0, 0, ")(", res);
else res.push_back(rev);
}
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
helper(s, 0, 0, "()", res);
return res;
}