forked from DengWangBao/Leetcode-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RemoveInvalidParentheses.java
121 lines (111 loc) · 4.11 KB
/
RemoveInvalidParentheses.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* TestCase
* ""
* "x("
* "("
*/
public class RemoveInvalidParentheses {
/**
* BFS法,遍历s,依次去掉一个'('或')',然后加入队列,判断是否是合法序列
* 遇到合法序列,则将该层所有序列都找出来
* 最差时间复杂度O(n*2^n)
*/
// 耗时97ms
public List<String> removeInvalidParentheses(String s) {
Queue<String> queue = new LinkedList<String>();
Queue<String> next = new LinkedList<String>();
HashSet<String> visited = new HashSet<String>();
List<String> result = new LinkedList<String>();
queue.add(s);
while (!queue.isEmpty()) {
String ss = queue.poll();
if (isValidParentheses(ss)) {
result.add(ss);
} else {
for (int i = 0; i < ss.length(); i++) {
/**
* 注意这里如果是非括号要跳过
*/
if (ss.charAt(i) != '(' && ss.charAt(i) != ')') {
continue;
}
String st = ss.substring(0, i) + ss.substring(i + 1);
if (visited.add(st)) {
next.add(st);
}
}
}
if (queue.isEmpty() && result.isEmpty()) {
queue.addAll(next);
next.clear();
}
}
return result;
}
private boolean isValidParentheses(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
count++;
} else if (s.charAt(i) == ')') {
// 这里要注意如果中途count<0了就非法了
if (--count < 0) {
return false;
}
}
}
// 最后的返回条件要注意
return count == 0;
}
/**
* 字符串不是合法的序列有两种情况,一种是'('和')'个数不对称,另一种是个数一样,但是顺序有问题,比如")("
* 所以判断字符串是否合法的指标有三个,即'('和')'个数一样,且count=0,但是在对比'('和')'个数时要注意,要用增量,而不是全量
* 如果用全量,最后返回的结果会包括不是最长的合法串,比如对于"()())()",返回的是"()()","()","(())","()()()","(())()"
* 如果用增量就不会有这个问题,只要给有问题的部分减到0即可,而不是全量部分减到0
*/
// 耗时9ms,时间复杂度仍然是O(n*2^n),只不过这里剪枝很多
public List<String> removeInvalidParentheses2(String s) {
int nL = 0, nR = 0;
// 这样统计出来的增量表示的是不平衡度,特别的有')(',nl和nr都为1
// 我们要给不平衡度都减到0,就是合法串了
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
nL++;
} else if (s.charAt(i) == ')') {
if (nL > 0) {
nL--;
} else {
nR++;
}
}
}
HashSet<String> set = new HashSet<>();
dfs(s, 0, set, "", nL, nR, 0);
return new LinkedList<String>(set);
}
private void dfs(String s, int i, HashSet<String> set, String t, int nL, int nR, int count) {
if (nL < 0 || nR < 0 || count < 0) {
return;
}
if (i == s.length()) {
if (nL == 0 && nR == 0 && count == 0) {
set.add(t);
}
return;
}
char c = s.charAt(i);
if (c == '(') {
dfs(s, i + 1, set, t, nL - 1, nR, count);
dfs(s, i + 1, set, t + "(", nL, nR, count + 1);
} else if (s.charAt(i) == ')') {
dfs(s, i + 1, set, t, nL, nR - 1, count);
dfs(s, i + 1, set, t + ")", nL, nR, count - 1);
} else {
dfs(s, i + 1, set, t + c, nL, nR, count);
}
}
}