题目链接:https://leetcode-cn.com/problems/remove-invalid-parentheses/
- 首先,先说下这题很恶心,没给数据量。
- 这道题感觉类似于什么括号匹配的题目(用右括号去匹配左括号),而且是最小,可能是贪心这类的,但是这道题要求的是所有可能的结果,多出来的可能是左括号、也可能是右括号,且删掉一个可能使前面 k k k个字符满足了有效括号,后面的删除结果也要随之改变了。
- 既然直接做会很麻烦,那么就暴力地去删除每一个字符,然后再对删除了一个的每一个串去删除第二个括号。每次删除都对已经删除括号个数相同的串进行,这很明显就是一层一层地去遍历解空间,没错就是bfs。
- 因为是bfs,所以最先满足题意的串一定是删除个数最少的。这一层里其他满足题意的答案也一定是最少的。
- 判断是否是有效的字符串:用一个变量 l l l去记录左括号的个数,出现右括号,说明可以匹配一个左括号: l l l- -,但是如果 l < 0 l<0 l<0,说明多出来了个右括号没有左括号与之匹配,直接返回 f a l s e false false。最后返回 l l l是否为0。
class Solution {
private:
vector<string> ans;
queue<string> Q;
unordered_set<string> rec;
bool isValid(const string & rhs){
int l = 0;
for (const char c: rhs){
if (c == '(') l++;
else if (c == ')') l--;
if (l < 0) return false;
}
return l == 0;
}
public:
vector<string> removeInvalidParentheses(string s) {
// bfs 暴力
Q.push(s);
int step = 0;
bool flag = false;
while (Q.size()){
int s = Q.size();
while (s-- > 0){
string c = Q.front(); Q.pop();
if (rec.count(c)) continue;
rec.insert(c);
if (isValid(c)) {
flag = true;
ans.push_back(c); continue;
}
string t;
int n = c.length();
for (int i = 0; i < n; i++){
t = c.substr(0, i) + c.substr(i + 1);
Q.push(t);
}
}
if (flag) break;
}
return ans;
}
};
- 这题也可以选择用 d f s dfs dfs,我们可以选择像 b f s bfs bfs那样,每一次删除一个字符。也可以去构造字符,对每一个字符选或不选,构造。
class Solution {
private:
vector<string> ans;
queue<string> Q;
unordered_set<string> rec;
string s;
int minDel = -1, n;
void dfs(string cur, int idx, int del, int l){ // 最坏情况:O(2^n)
if (minDel != -1 && del > minDel) return;
if (l < 0) return;
if (idx == n) {
if (rec.count(cur)) return;
rec.insert(cur);
// cout << cur << " ";
if (l == 0){
if (minDel == -1 || minDel > del)
minDel = del, ans = {};
if (minDel == del) ans.push_back(cur);
}
return;
}
if (s[idx] != '(' && s[idx] != ')')
dfs(cur + s[idx], idx + 1, del, l);
else {
dfs(cur, idx + 1, del + 1, l);
if (s[idx] == ')') l--;
else l++;
dfs(cur + s[idx], idx + 1, del, l);
}
}
bool isValid(const string & rhs){
int l = 0;
for (const char c: rhs){
if (c == '(') l++;
else if (c == ')') l--;
if (l < 0) return false;
}
return l == 0;
}
public:
vector<string> removeInvalidParentheses(string s) {
// 左括号用右括号去匹配
this->s = s, this->n = s.length();
rec.clear();
dfs("", 0, 0, 0);
cout << minDel;
return ans;
}
};