难度困难215
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 (
和 )
以外的字符。
示例 1:
输入: "()())()" 输出: ["()()()", "(())()"]
示例 2:
输入: "(a)())()" 输出: ["(a)()()", "(a())()"]
示例 3:
输入: ")(" 输出: [""]
class Solution {
Set<String> ans = new HashSet<>();
public List<String> removeInvalidParentheses(String s) {
int n = s.length(), left = 0, right = 0;
for(int i = 0; i < n; ++i){
if(s.charAt(i) == '('){
left++;
}else if(s.charAt(i) == ')'){
if(left != 0)left--;
else right++;
}
}
dfs(s, 0, left, right);
return new ArrayList<String>(ans);
}
boolean isChecked(String s){
int cnt = 0;
for(int i = 0; i < s.length(); ++i){
if(s.charAt(i) == '('){
cnt++;
}else if(s.charAt(i) == ')'){
cnt--;
if(cnt < 0)return false;
}
}
return cnt == 0;
}
void dfs(String s, int index, int left, int right){
if(index == s.length()){
if(isChecked(s))ans.add(s);
return;
}
//与其他回溯题目不一样的是,此处可以将for循环变为枚举,枚举不同的类型,for循环是针对相同的类型,枚举可以定制化不同情况
//不删除的情况
dfs(s, index + 1, left, right);
//删除(
if(left > 0 && s.charAt(index) == '('){
String res = s;
s = s.substring(0, index) + s.substring(index + 1, s.length());
dfs(s, index, left - 1, right);
s = res;
}
//删除)
if(right > 0 && s.charAt(index) == ')'){
String res = s;
s = s.substring(0, index) + s.substring(index + 1, s.length());
dfs(s, index, left, right - 1);
s = res;
}
}
}