建立决策树的BFS、DFS题。
有两种解法。
我的两种解法优化的都不是很好,不论是时间还是空间都没有进50%
BFS解法
要用set来解决掉重复元素。
用unordered_set要比set快很多
https://leetcode-cn.com/problems/remove-invalid-parentheses/
class Solution {
public:
vector<string> res;
void BFS(string s) {
queue<string> qu;
queue<int> temp;
unordered_set<string> st;
qu.push(s);
temp.push(0);
st.insert(s);
int num;
int nowLevel;
int minLevel = 999;
while (!qu.empty()) {
s = qu.front(); qu.pop();
nowLevel = temp.front(); temp.pop();
num = 0;
for (int i = 0; i < s.size(); i ++) {
if (s[i] == '(') num ++;
else if (s[i] == ')') num --;
if (num < 0) break;
}
if (nowLevel > minLevel) return ;
if (num == 0 && count(res.begin(), res.end(), s) == 0) {
res.push_back(s);
minLevel = nowLevel;
}
string ts = s;
string::iterator it;
for (it = s.begin(); it != s.end(); it ++) {
if (!(*it == '(' || *it == ')')) continue;
s.erase(it);
if (!st.count(s)) {
qu.push(s);
st.insert(s);
temp.push(nowLevel + 1);
}
s = ts;
}
}
}
vector<string> removeInvalidParentheses(string s) {
BFS(s);
return res;
}
};
DFS解法:疯狂剪枝
剪枝1:提前计算好需要删除的左右括号个数m,当到达删除个数时就判断。相当于只留下决策树的前m层
剪枝2:可能会出现相同的字符串,将相同的剪掉。比如DFS的过程中出现了“(())”,那么该字符串就不能再次出现。
总结:
可以通过两个方面剪枝,
1.层数
2.删去重复个数
class Solution {
public:
vector<string> res;
unordered_set<string> st;
bool check(string s) {
int num = 0;
for (char i : s) {
if (i == '(') num ++;
else if (i == ')') num --;
if (num < 0) return false;
}
if (num == 0) return true;
else return false;
}
void DFS(string s, int left, int right) {
st.insert(s);
if (left == 0 && right == 0) {
if (check(s)) {
res.push_back(s);
}
return ;
}
string::iterator it;
string ts = s;
for (it = s.begin(); it != s.end(); it ++) {
if (*it == '(' && left > 0) {
s.erase(it);
if (!st.count(s)) DFS(s, left - 1, right);
s = ts;
} else if (*it == ')' && right > 0) {
s.erase(it);
if (!st.count(s)) DFS(s, left, right - 1);
s = ts;
}
}
}
vector<string> removeInvalidParentheses(string s) {
int left = 0, right = 0;
for (int i = 0; i < s.size(); i ++) {
if (s[i] == '(') {
left ++;
} else if (s[i] == ')') {
if (left > 0) left --;
else right ++;
}
}
DFS(s, left, right);
return res;
}
};