301. 删除无效的括号
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 ( 和 ) 以外的字符。
示例 1:
输入: "()())()"
输出: ["()()()", "(())()"]
示例 2:
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]
示例 3:
输入: ")("
输出: [""]
DFS(超时)
cnt判断当前括号是否符合要求;
给出结果条件,符合时加入结果set;
最后返回set转vector。
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
maxi=0;
temp="";
dfs(s,0,0);
return vector<string> (SET.begin(),SET.end()); //set转vector
}
private:
vector<string> res;
set<string> SET;
string temp;
int maxi;
void dfs(string s,int cnt,int i){
if(cnt<0) return;
if(i==s.length()&&cnt==0){
if(temp.length()>maxi){
maxi=temp.length();
SET.clear();
SET.insert(temp);
}else if(temp.length()==maxi) SET.insert(temp);
return;
}
if(i==s.length()) return;
temp+=s[i];
if(s[i]=='(') dfs(s,cnt+1,i+1);
else if(s[i]==')') dfs(s,cnt-1,i+1);
else dfs(s,cnt,i+1);
temp.pop_back();
if(s[i]=='('||s[i]==')') dfs(s,cnt,i+1);
return;
}
};
DFS+剪枝
先求出需要删除的左右括号个数,记录dfs已删除的左右括号,若超过事先计算的,直接剪枝;
返回set转vector。
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
maxi=0;
//计算需要删除的括号数
int left=0;int right=0;
ldel=0;rdel=0;
for(char t:s){
if(t=='(') left++;
if(t==')'){
if(right==left) rdel++;
else right++;
}
}
ldel=left-right;
temp="";
dfs(s,0,0,0,0);
return vector<string> (SET.begin(),SET.end()); //set转vector
}
private:
vector<string> res;
set<string> SET;
string temp;
int maxi;
int ldel;
int rdel;
void dfs(string s,int cnt,int dell,int delr,int i){
if(cnt<0) return;
if(dell>ldel||delr>rdel) return;
if(i==s.length()&&cnt==0){
if(temp.length()>maxi){
maxi=temp.length();
SET.clear();
SET.insert(temp);
}else if(temp.length()==maxi) SET.insert(temp);
return;
}
if(i==s.length()) return;
temp+=s[i];
if(s[i]=='(') dfs(s,cnt+1,dell,delr,i+1);
else if(s[i]==')') dfs(s,cnt-1,dell,delr,i+1);
else dfs(s,cnt,dell,delr,i+1);
temp.pop_back();
if(s[i]=='(') dfs(s,cnt,dell+1,delr,i+1);
else if(s[i]==')') dfs(s,cnt,dell,delr+1,i+1);
return;
}
};
BFS(超时)
每次试图删除每一个括号,进行判断;
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
queue<string> Q;
Q.push(s);
while(!Q.empty()){
int size=Q.size();
for(int i=0;i<size;i++){
tmp=Q.front();
Q.pop();
if(isvalid(tmp)) S.insert(tmp);
if(S.size()==0){
for(int i=0;i<tmp.length();i++)
Q.push(tmp.substr(0,i)+tmp.substr(i+1));
}
}
if(S.size()>0) break;
}
return vector<string>(S.begin(),S.end());
}
private:
set<string> S;
string tmp;
bool isvalid(string s){
int count=0;
for(char t:s)
{
if(t=='(') count++;
else if(t==')') count--;
if(count<0) return false;
}
return count==0;
}
};
BFS+visited剪枝
将以添加过的字符串保存,减少入队次数;
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
queue<string> Q;
set<string> visited;
Q.push(s);
while(!Q.empty()){
int size=Q.size();
for(int i=0;i<size;i++){
tmp=Q.front();
Q.pop();
if(isvalid(tmp)) S.insert(tmp);
if(S.size()==0){
for(int i=0;i<tmp.length();i++)
if(visited.find(tmp.substr(0,i)+tmp.substr(i+1))==visited.end()){
Q.push(tmp.substr(0,i)+tmp.substr(i+1));
visited.insert(tmp.substr(0,i)+tmp.substr(i+1));
}
}
}
if(S.size()>0) break;
}
return vector<string>(S.begin(),S.end());
}
private:
set<string> S;
string tmp;
bool isvalid(string s){
int count=0;
for(char t:s)
{
if(t=='(') count++;
else if(t==')') count--;
if(count<0) return false;
}
return count==0;
}
};
再优化
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
queue<string> Q;
unordered_map<string,bool> visited;
Q.push(s);
while(!Q.empty()){
int size=Q.size();
for(int i=0;i<size;i++){
tmp=Q.front();
Q.pop();
if(isvalid(tmp)) S.insert(tmp);
if(S.size()==0){
for(int i=0;i<tmp.length();i++)
if((tmp[i]=='('||tmp[i]==')')&&!visited[tmp.substr(0,i)+tmp.substr(i+1)]){
Q.push(tmp.substr(0,i)+tmp.substr(i+1));
visited[tmp.substr(0,i)+tmp.substr(i+1)]=1;
}
}
}
if(S.size()>0) break;
}
return vector<string>(S.begin(),S.end());
}
private:
set<string> S;
string tmp;
bool isvalid(string s){
int count=0;
for(char t:s)
{
if(t=='(') count++;
else if(t==')') count--;
if(count<0) return false;
}
return count==0;
}
};
BFS剪枝后不如dfs剪枝快,BFS对前面的每个节点都需要遍历;
DFS可以剪掉无用节点;

本文探讨了如何使用深度优先搜索(DFS)和广度优先搜索(BFS)解决301题——删除无效的括号问题。通过剪枝策略和去重方法,优化算法以提高效率。示例展示了不同方法的应用,并指出DFS在剪枝方面更优。
645

被折叠的 条评论
为什么被折叠?



