给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
思路: 回溯法,刚开始没有想到好的办法进行剪枝,后来看了评论才知道,定义左右剩余的括号数,进行递归,真的好思路,好方法。
class Solution {
public List<String> generateParenthesis(int n) {
List<String> list = new ArrayList<>();
if (n == 0)
return list;
dfs(list,n,n,"");
return list;
}
public void dfs(List<String> list,int l,int r,String s) {
if (l == 0 && r == 0)
{
list.add(s);
return;
}
if (l > 0) {
dfs(list,l-1,r,s+"(");
}
if (l < r && r > 0) {
dfs(list,l,r-1,s+")");
}
}
}
动态规划类似解法:
public List<String> generateParenthesis(int n) {
if (n == 0) {
return new ArrayList<>();
}
// 这里 dp 数组我们把它变成列表的样子,方便调用而已
List<List<String>> dp = new ArrayList<>(n);
List<String> dp0 = new ArrayList<>();
dp0.add("");
dp.add(dp0);
for (int i = 1; i <= n; i++) {
List<String> cur = new ArrayList<>();
for (int j = 0; j < i; j++) {
List<String> str1 = dp.get(j);
List<String> str2 = dp.get(i - 1 - j);
for (String s1 : str1) {
for (String s2 : str2) {
// 枚举右括号的位置
cur.add("(" + s1 + ")" + s2);
}
}
}
dp.add(cur);
}
return dp.get(n);
}