- 题目描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
来源:LeetCode
- 示例
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
- 思路分析
- 方法1:分析n对括号的所有可能组成。比如n为3的时候,所有有效括号组合分为以下几种情况:1)没有单个括号,所有括号都被嵌套或嵌套别的括号:这种情况下,相当于给n-1个括号的所有情况都加上外括号;2)结尾有一个单括号:即为n-1个括号与1个括号的组合;……以此类推;n)结尾有n-1个单括号:即为1个括号与n-1个括号的组合。因此按照这个思路,依次求出1~n-1的所有情况即可。
- 方法2:深度优先搜索DFS。用left表示已经用过的左括号的数目,right表示已经用过的右括号的数目;当left用完后,开始用right,都用完则找到一个满足的结果,并且回退到left少用一个的情况,以此类推。
- JAVA实现
- 方法1
public class GenerateParenthesis {
public static List<String> generateParenthesis(int n) {
List<String>[] parenthesis = new ArrayList[n];
if(n == 0) return parenthesis[n-1];
parenthesis[0] = new ArrayList<>();
parenthesis[0].add("()");
int number = 2; //对应的index是number-1
while(number <= n) {
//0个单独括号的情况,等同于n-1个括号的所有情况都加上一个外括号
parenthesis[number-1] = new ArrayList<>();
for(String last:parenthesis[number-2]) {
String s = "("+last+")";
parenthesis[number-1].add(s);
}
//1~n-1个单独括号的情况
for(int i=1; i<number; i++) { //前面是i个括号的组合
int j = number-i; //后面是j个括号的组合
for(String before:parenthesis[i-1]) {
for(String after:parenthesis[j-1]) {
if(!parenthesis[number-1].contains(before+after)) parenthesis[number-1].add(before+after); //排除全是单括号的重复情况
}
}
}
number++;
}
return parenthesis[n-1];
}
}
- 方法2
public class GenerateParenthesis {
public static List<String> generateParenthesis_dfs(int n) {
int left = 0, right = 0;
String s="";
List<String> parenthesis = new ArrayList<>();
generate_dfs(parenthesis, left, right, s, n);
return parenthesis;
}
public static void generate_dfs(List<String> parenthesis, int left, int right, String s, int n) {
String mid = "";
if(right > n || left > n) return;
else if(right == n && left == n) parenthesis.add(s);
else if(left >= right){
generate_dfs(parenthesis, left+1, right, s+"(", n);
generate_dfs(parenthesis, left, right+1, s+")", n);
}
return;
}
}