/*
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
*/
/*
思路:回溯剪枝 时间复杂度为O(n2^n) 如果剪枝严格到一定程度,可不需要调用isMatch()验证,时间复杂度降为O(2^n).
当限制趋于严格,leetCode击败对手从5%变为97%
剪枝函数 1.左括号数不能超过总括号数一半
2.当前右括号数不能多于左括号数
3.最后一个位置不能填左括号,第一个位置不能填右括号.
*/
4
1 class Solution23 {
2
3 public List<String> generateParenthesis(int n) {
4 char[] solveArray = new char[2 * n];
5 List<String> list = new ArrayList<>();
6 search(2 * n, 0, solveArray, list, 0, 0);
7 return list;
8 }
9
10 private void search(int n, int level, char[] solveArray, List<String> list, int left, int right) {
11
12 if (level == n) {
13 //if (isMatch(solveArray)) { //当限制趋于严格,不必再花费O(n)的时间检查括号匹配是否正确
14 list.add(String.valueOf(solveArray));
15 // }
16 } else {
17 if (right < left) {
18 solveArray[level] = ')';
19 search(n, level + 1, solveArray, list, left, right + 1);
20 }
21 if (left < n / 2 && level != n - 1) {
22 solveArray[level] = '(';
23 search(n, level + 1, solveArray, list, left + 1, right);
24 }
25 }
26 }
27
28 private boolean isMatch(char[] solveArray) {
29 System.out.println(solveArray);
30 Stack<Character> stack = new Stack<>();
31 for (char c : solveArray) {
32 if (c == '(') {
33 stack.push('(');
34 } else {
35 if (stack.isEmpty()) {
36 return false;
37 }
38 stack.pop();
39 }
40 }
41 return stack.isEmpty();
42 }
43 }