301.删除无效的括号 (Hard)*
题目描述*
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 ( 和 ) 以外的字符。
示例*
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]
代码*
dfs 或 bfs
dfs,首先要求出不合法的左右括号的个数,一次遍历即可,然后 dfs 寻找结果。
bfs 就比较慢了,不太好优化,一层一层遍历。
还有一种带哥的解法,还没太看明白。。。
class Solution {
private:
bool isValid(string s) {
int cnt = 0;
for(auto c : s) {
if(c == '(') {
cnt++;
}else if(c == ')') {
cnt--;
if(cnt < 0) {
return false;
}
}
}
return cnt == 0;
}
void dfs(string s, int start, int cntLeft, int cntRight, vector<string>& res) {
if(cntLeft == 0 && cntRight == 0) {
if(isValid(s)) {
res.push_back(s);
}
return;
}
for(int i = start; i < s.length(); i++) {
// 去重
if(i - 1 >= start && s[i] == s[i - 1]) {
continue;
}
if(cntLeft > 0 && s[i] == '(') {
dfs(s.substr(0, i) + s.substr(i + 1), i, cntLeft - 1, cntRight, res);
}
if(cntRight > 0 && s[i] == ')') {
dfs(s.substr(0, i) + s.substr(i + 1), i, cntLeft, cntRight - 1, res);
}
}
}
public:
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
if(s.length() == 0) {
res.push_back("");
return res;
}
int cntLeft = 0, cntRight = 0;
for(auto c : s) {
if(c == '(') {
cntLeft++;
}else if(c == ')') {
if(cntLeft > 0) {
cntLeft--;
}else {
cntRight++;
}
}
}
dfs(s, 0, cntLeft, cntRight, res);
return res;
}
};
class Solution {
private:
bool isValid(string s) {
int cnt = 0;
for(auto c : s) {
if(c == '(') {
cnt++;
}else if(c == ')') {
cnt--;
if(cnt < 0) {
return false;
}
}
}
return cnt == 0;
}
public:
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
queue<string> q;
q.push(s);
unordered_set<string> visited;
visited.insert(s);
bool ifContinue = true;
while(!q.empty()) {
string cur = q.front();
q.pop();
if(isValid(cur)) {
res.push_back(cur);
ifContinue = false;
}
if(!ifContinue) {
continue;
}
for(int i = 0; i < cur.length(); i++) {
if(cur[i] == '(' || cur[i] == ')') {
string tmp = cur.substr(0, i) + cur.substr(i + 1);
if(!visited.count(tmp)) {
q.push(tmp);
visited.insert(tmp);
}
}
}
}
return res;
}
};
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
vector<string> res;
remove(move(s), {'(', ')'}, 0, 0, res);
return res;
}
void remove(std::string s, const vector<char>& par, int m, int n, vector<string>& res) {
int stack = 0, i = m;
for (int i = m; i < s.length(); ++i) {
if (s[i] == par[0]) stack++;
if (s[i] == par[1]) stack--;
if (stack >= 0) continue;
// "右"括号多出来了,删除一个右括号
for (int j = n; j <= i; ++j) {
if (s[j] == par[1] && (j == n || s[j-1] != par[1])) {
auto ss = s.substr(0, j) + s.substr(j + 1);
remove(move(ss), par, i, j, res);
}
}
return;
}
reverse(s.begin(), s.end());
if (par[0] == '(') {
remove(move(s), {par[1], par[0]}, 0, 0, res);
} else {
res.push_back(move(s));
}
}
};
最后更新: July 23, 2022