22.括号生成
题意描述:
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
思路:
首先是受到动态规划思想的影响,想从上一个状态的括号排序来生成下一个。具体是获取上一个n的所有括号序列,然后对每个括号组成加上(+s+),()+s,s+(),还要切割s内部的合法括号子串进行处理,最后可以ac,但方法有点笨。
代码:
public List<String> generateParenthesis(int n) {
List<HashSet<String>> list = new ArrayList<>();
HashSet<String> h1 = new HashSet<>();
h1.add("()");
list.add(h1);
for (int i = 2; i <= n; i++) {
HashSet<String> front = list.get(i-2);
HashSet<String> now = new HashSet<>();
for (String s : front) {
int left = 0;
int j = 0;
int ls = 0;
int rs = 0;
while (j < s.length()) {
if (s.charAt(j) == '(')
ls++;
else if (s.charAt(j) == ')')
rs++;
if (ls == rs && ls != 0) {
String tl = s.substring(0,left);
String tm = s.substring(left,j+1);
String tr = s.substring(j+1);
String temans1 = tl + "(" + tm + ")" + tr;
String temans2 = tl + "()" + tm + tr;
String temans3 = tl + tm + "()" + tr;
now.add(temans1);
now.add(temans2);
now.add(temans3);
if (j == s.length()-1)
left++;
ls = 0;
rs = 0;
}
j++;
}
}
list.add(now);
}
return new ArrayList<String>(list.get(n-1));
}
然后使用回溯进行括号生成,记录左括号和右括号的数量,当numLeft == numRight == n时,找到一个合法的序列,生成时注意当numLeft>numRight时才可以继续添加右括号。
代码:
class Solution {
List<String> ans;
List<String> path;
public void getPath(int n, int left, int right) {
if (left == n && right == n) {
String tem = "";
for (String s : path)
tem += s;
ans.add(tem);
return;
}
if (left < n) {
path.add("(");
left++;
getPath(n,left,right);
left--;
path.remove(path.size()-1);
}
if (right < n && right < left) {
path.add(")");
right++;
getPath(n,left,right);
right--;
path.remove(path.size()-1);
}
}
public List<String> generateParenthesis(int n) {
ans = new ArrayList<>();
path = new ArrayList<>();
int left = 0;
int right = 0;
getPath(n,left,right);
return ans;
}
}