LeetCode HOT100 - 删除无效的括号
首先是括号序列是否合法的判断
一个经典的判断形式是从左到右计数,( 为 1, ) 为 -1 ,中途如果小于 0 了,那么不合法,最后如果是 0 ,那么合法,否则也不合法
接着回到这一题
删除最小数量的无效括号,使得输入的字符串有效
1 <= s.length <= 25 长度并不大,可以考虑搜索
搜索的话要么是深度优先,要么是广度优先
从最小值的角度来说,广度优先自然一些
BFS 就是一层一层,第几层相当于删几个括号,这样如果某一层搜到了合法的字符,我们就不用继续扩展下一层了
bfs 的写法就是要注意我们是用队列存的,表示的是要操作的
但是每次我们是对一层进行操作,为了知道队列中哪些是这一层的,我们要记录层的大小来操作
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
auto check = [&](string t) -> int {
int cnt = 0;
for (auto i : t) {
if (i != '(' && i != ')') {
continue;
}
cnt += i == '(' ? 1 : -1;
if (cnt < 0) {
return 0;
}
}
return cnt == 0;
};
queue<string> q;
vector<string> ans;
unordered_set<string> vis;
q.push(s);
vis.insert(s);
int k = 0;
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
string t = q.front();
q.pop();
if (check(t)) {
k = 1;
ans.emplace_back(t);
}
if (k) {
continue;
}
for (int j = 0; j < t.size(); j++) {
if (t[j] != '(' && t[j] != ')') {
continue;
}
string tmp = t.substr(0, j) + t.substr(j + 1);
if (!vis.count(tmp)) {
q.push(tmp);
vis.insert(tmp);
}
}
}
if (k) {
break;
}
}
return ans;
}
};
再就是 dfs ,也是搜索状态,不过 dfs 一般就是要提前维护一些信息了,否则我们不知道成功的那个是不是最优
但实际上,我们要删除多少是可以提早知道的,同样从我们那个判断合法性的函数出发
从左到右扫描:
- 遇到
(:lremove++ - 遇到
):- 如果此时
lremove > 0,说明它可以和前面的左括号匹配,于是lremove-- - 否则说明这个
)多余,rremove++
最后:
- 如果此时
lremove表示多余的左括号数rremove表示多余的右括号数
dfs 中,我们就是根据这两个参数,来判断这个括号能否删除
当然,dfs 的核心是剪枝,不然其状态数会很多,也就是到了什么程度之后,我们没必要继续往深的搜索了
-
比如字符串里有
"(((",删第一个和删第二个,结果其实一样。
所以如果当前位置字符和前一个一样,就跳过,避免重复。 -
如果当前剩余字符数都不足以删完
lremove + rremove,那这条路不可能成功,直接返回。 -
合法性检查,已经合法了,当然不用继续了,更深层一定不优
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
auto check = [&](string t) -> int {
int cnt = 0;
for (auto i : t) {
if (i != '(' && i != ')') {
continue;
}
cnt += i == '(' ? 1 : -1;
if (cnt < 0) {
return 0;
}
}
return cnt == 0;
};
int l = 0, r = 0;
for (auto i : s) {
if (i == '(') {
l++;
} else if (i == ')') {
if (l) {
l--;
} else {
r++;
}
}
}
vector<string> ans;
unordered_set<string> st;
auto dfs = [&](auto self, string t, int u, int l, int r) -> void {
if (l == 0 && r == 0) {
if (check(t) && !st.count(t)) {
ans.emplace_back(t);
st.insert(t);
}
return;
}
for (int i = u; i < t.size(); i++) {
if (i > u && t[i] == t[i - 1]) {
continue;
}
if (l + r > t.size() - i) {
return;
}
if (l && t[i] == '(') {
self(self, t.substr(0, i) + t.substr(i + 1), i, l - 1, r);
}
if (r && t[i] == ')') {
self(self, t.substr(0, i) + t.substr(i + 1), i, l, r - 1);
}
}
};
dfs(dfs, s, 0, l, r);
return ans;
}
};

浙公网安备 33010602011771号