【LeetCode每日一题】301. 删除无效的括号【困难】暴搜
给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
返回所有可能的结果。答案可以按 任意顺序 返回。
示例 1:
输入:s = "()())()" 输出:["(())()","()()()"] 示例 2:
输入:s = "(a)())()" 输出:["(a())()","(a)()()"] 示例 3:
输入:s = ")(" 输出:[""]
提示:
1 <= s.length <= 25 s 由小写英文字母以及括号 '(' 和 ')' 组成 s 中至多含 20 个括号
题解:
这道题给人的感觉就是要使用回溯,但是自己还是没有成功实现,参考了题解的思路,然后自己打了一遍。
class Solution {
public:
bool isValid(string str) {
int count = 0;
for (char c : str) {
if (c == '(') {
count++;
} else if (c == ')') {
count--;
if (count < 0) {
return false;
}
}
}
return count == 0;
}
vector<string> removeInvalidParentheses(string s) {
vector<string> ans;
unordered_set<string> currSet;
currSet.insert(s);
while (true) {
for (auto & str : currSet) {
if (isValid(str))
ans.emplace_back(str);
}
if (ans.size() > 0) {
return ans;
}
unordered_set<string> nextSet;
for (auto & str : currSet) {
for (int i = 0; i < str.size(); i++) {
if (i > 0 && str[i] == str[i - 1]) {
continue;
}
if (str[i] == '(' || str[i] == ')') {
nextSet.insert(str.substr(0, i) + str.substr(i + 1, str.size()));
}
}
}
currSet = nextSet;
}
}
};
class Solution {
public:
bool checkValid(const string & str, int lmask, vector<int> & left, int rmask, vector<int> & right) {
int pos1 = 0;
int pos2 = 0;
int cnt = 0;
for (int i = 0; i < str.size(); i++) {
if (pos1 < left.size() && i == left[pos1]) {
if (!(lmask & (1 << pos1))) {
cnt++;
}
pos1++;
} else if (pos2 < right.size() && i == right[pos2]) {
if (!(rmask & (1 << pos2))) {
cnt--;
if (cnt < 0) {
return false;
}
}
pos2++;
}
}
return cnt == 0;
}
string recoverStr(const string & str, int lmask, vector<int> & left, int rmask, vector<int> & right){
string ans;
int pos1 = 0;
int pos2 = 0;
for (int i = 0; i < str.size(); i++) {
if (pos1 < left.size() && i == left[pos1]) {
if (!(lmask & (1 << pos1))){
ans.push_back(str[i]);
}
pos1++;
} else if (pos2 < right.size() && i == right[pos2]) {
if (!(rmask & (1 << pos2))) {
ans.push_back(str[i]);
}
pos2++;
} else {
ans.push_back(str[i]);
}
}
return ans;
}
vector<string> removeInvalidParentheses(string s) {
int lremove = 0;
int rremove = 0;
vector<int> left;
vector<int> right;
vector<string> ans;
unordered_set<string> cnt;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') {
left.push_back(i);
lremove++;
} else if (s[i] == ')') {
right.push_back(i);
if (lremove == 0) {
rremove++;
} else {
lremove--;
}
}
}
int m = left.size();
int n = right.size();
vector<int> maskArr1;
vector<int> maskArr2;
for (int i = 0; i < (1 << m); i++) {
if (__builtin_popcount(i) != lremove) {
continue;
}
maskArr1.push_back(i);
}
for (int j = 0; j < (1 << n); j++) {
if (__builtin_popcount(j) != rremove) {
continue;
}
maskArr2.push_back(j);
}
for (auto mask1 : maskArr1) {
for (auto mask2 : maskArr2) {
if (checkValid(s, mask1, left, mask2, right)) {
cnt.insert(recoverStr(s, mask1, left, mask2, right));
}
}
}
for (auto v : cnt) {
ans.emplace_back(v);
}
return ans;
}
};