1.题目
思路:使用DFS+剪枝的方法解(因为要从左往右一个个判断,每次判断都会面临一些选择)
(1)首先计算出不符合配对要求的左右括号的个数
(2)每次递归都会遇到左括号、右括号、其他字符
- 如果是左括号(你可以删除或者不删(等后面再删除,但是先得记着leftCount)
- 如果是右括号,因为rightDeleted>0删除,或者不删,因为leftCount不为0,为了和左括号配对,添加右括号,否则return剪枝。
- 如果是其他符号,直接添加。
(3)遍历完字符串,满足leftDeleted、rightDeleted、leftCount为0(不符合要求的左右括号必须删除,没有删除的左括号也得使用右括号类配对),这样才会生成符合要求的字符串。
2.解法
class Solution {
private HashSet<String> set = new HashSet<String>();
public List<String> removeInvalidParentheses(String s) {
// 集合中可以存放无重复的值
ArrayList<String> arr = new ArrayList<String>();
int leftDeleted=0, rightDeleted=0;
for(int i=0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch == '(') {
leftDeleted++;
}else if(ch == ')') {
if (leftDeleted > 0) {
leftDeleted--;
}else {
rightDeleted++;
}
}
}
dfs(s, 0, 0, leftDeleted, rightDeleted, new StringBuilder());
arr.addAll(set);
return arr;
}
private void dfs(String str, int index, int left, int leftDeleted, int rightDeleted, StringBuilder sb) {
if(index == str.length()) {
// 否合所有的条件
if(left == 0 && leftDeleted == 0 && rightDeleted == 0) {
set.add(sb.toString());
return;
}
} else {
char cur = str.charAt(index);
if(cur == '(') {
// 1.删除‘(’
if(leftDeleted > 0) {
StringBuilder newSb = new StringBuilder(sb);
dfs(str, index+1, left, leftDeleted-1, rightDeleted, newSb);
}
// 2.不删除,删后面的‘(’
// 不使用同一StringBuilder
StringBuilder newSb = new StringBuilder(sb);
newSb.append(cur);
dfs(str, index+1, left+1, leftDeleted, rightDeleted, newSb);
}else if(cur == ')') {
// 1.删除
if(rightDeleted > 0) {
StringBuilder newSb = new StringBuilder(sb);
dfs(str, index+1, left, leftDeleted, rightDeleted-1, newSb);
}
// 2.不删除的话,是因为有匹配的‘(’
if(left > 0) {
StringBuilder newSb = new StringBuilder(sb);
newSb.append(cur);
dfs(str, index+1, left-1, leftDeleted, rightDeleted, newSb);
}else {
// 如果没有左括号就结束,剪枝
return;
}
}else {
StringBuilder newSb = new StringBuilder(sb);
newSb.append(cur);
dfs(str, index+1, left, leftDeleted, rightDeleted, newSb);
}
}
}
}
4.想法轨迹(不用看哈~~)
只考虑一个方案,而且这时候只有一个异常括号:
( 和 )的数量要匹配,所以当遇到( 的时候++count,遇到 )的时候 --count,但是要用pre保存异常的括号,最后要删除它。
public class DeadLockDemo {
public void delete(String str) {
int pre = 0;
int count = 0;
for(int i = 0; i < str.length(); i++) {
if (str.charAt(i) != ')') {
if(str.charAt(i) == '(') {
++count;
if(count >= 2) {
pre = i;
}
}
} else {
if(count > 0) {
--count;
if(count == 0) {
pre = -1;
}
} else {
pre = i;
}
}
}
if (count == 0) {
// 说明包含异常括号
if(pre != -1) {
// substring不包含最后一个元素
String s = str.substring(0, pre) + str.substring(pre+1, str.length());
System.out.println(s);
}else {
// 不包含异常括号
System.out.println(str);
}
} else {
System.out.println("");
}
}
public static void main(String[] args) {
DeadLockDemo demo = new DeadLockDemo();
demo.delete("(a)())()");
}
}