一、题目
数字 n 代表生成括号的 对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入: n = 3
输出: ["((()))","(()())","(())()","()(())","()()()"]
二、方法一
我们将一对括号()看做一个整体。
要求 n对括号 的有效组合,假设我们已知 n-1对括号 的有效组合,只需要将一对括号()插入其中的各个位置就可以得到。
另外,由于得到的结果有可能会有重复,我们采用 HashSet 去重。
public List<String> generateParenthesis2(int n) {
List<String> list=new ArrayList<>();
String onePair="()";
list.add(onePair);
if(n==1)
return list;
for(int i=1;i<n;i++) {
HashSet<String> set=new HashSet<>();
for(String pair:list) {
//i对括号,包括2*i个括号,也就2*i+1个可以插入的位置
for(int j=0;j<=2*i;j++) {
//插入括号
StringBuilder sb=new StringBuilder(pair);
String tempString=sb.insert(j, onePair).toString();
set.add(tempString);
}
}
list=new ArrayList<>(set);
}
return list;
}
三、方法二
这里我们采用“减法”,left 代表剩余的左括号数量,right 代表剩余的右括号数量,以 n=2 为例,画树形结构图如下:
从中可以看出,为了生成 有效的 括号组合:
- 剩余的左括号和右括号数量相等的时候,只能填入左括号。
- 剩余的左括号数量小于右括号的时候,既可以填入左括号,也可以填入右括号。
- 当剩余的左括号和剩余的右括号数量都为0时结算。
我们只要采用 深度优先搜索 方法,就可以得到相应的括号组合。
class Solution {
List<String> list=new ArrayList<>();
public List<String> generateParenthesis(int n) {
dfs("", n,n);
return list;
}
/**
* 根据剩余左括号数,右括号数,生成一个包含“n对括号”的有效字符串
* @param str 已经填入的字符串
* @param left 剩余的左括号数量
* @param right 剩余的右括号数量
*/
public void dfs(String str,int left,int right) {
if(left==0&&right==0) {
list.add(str);
return;
}
if(left==right) {
dfs(str+"(",left-1,right);
}else {
if(left>0) {
dfs(str+"(", left-1, right);
}
dfs(str+")", left, right-1);
}
}
}