删除无效的括号
题目:
给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
返回所有可能的结果。答案可以按 任意顺序 返回。
示例 1:
输入:s = “()())()”
输出:["(())()","()()()"]
示例 2:
输入:s = “(a)())()”
输出:["(a())()","(a)()()"]
示例 3:
输入:s = “)(”
输出:[""]
解题思路: 首先计算出字符串中多余的左右括号数, 再用dfs来枚举出删除相应数目的左右括号(优先删除右括号, 防止首字符是右括号导致所有结果都无效)后的字符串是否是有效字符串
class Solution {
private List<String> ans = new ArrayList();
public List<String> removeInvalidParentheses(String s) {
char[] ch = s.toCharArray();
int l = 0, r = 0;
// 计算多余的左右括号
for(char c : ch) {
if(c == '(') {
l++;
} else if(c == ')') {
if(l > 0) {
l--;
} else {
r++;
}
}
}
dfs(s, l, r, 0);
return ans;
}
private boolean isValid(String s) {
char[] ch = s.toCharArray();
int count = 0;
for(char c : ch) {
if(c == '(') {
count++;
} else if(c == ')') {
count--;
}
if(count < 0) {
return false;
}
}
return count == 0;
}
private void dfs(String s, int l, int r, int cur) {
if(l == 0 && r == 0) {
if(isValid(s)) {
ans.add(s);
}
return ;
}
for(int i = cur; i < s.length(); i++) {
// 相邻字符相同删除最后一个即可 防止答案重复
if(i != cur && s.charAt(i) == s.charAt(i - 1)) {
continue ;
}
char c = s.charAt(i);
StringBuffer sb = new StringBuffer(s);
if(c == ')' && r > 0) {
dfs(sb.deleteCharAt(i).toString(), l, r - 1, i);
} else if(c == '(' && l > 0) {
dfs(sb.deleteCharAt(i).toString(), l - 1, r, i);
}
}
}
}