题目:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
以下是根据leetcode中的解答整理的思路:
思路1:回溯法
有一些像排列组合的思想。首先添加的第一个一定是个左括号,之后添加括号就有两种选择。在添加的过程中要注意两种括号的数量各自不能超过n.
代码:
class Solution {
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList();
backtrack(ans, "", 0, 0, n);
return ans;
}
public void backtrack(List<String> ans, String cur, int open, int close, int max){
if (cur.length() == max * 2) { //判断总的括号数量
ans.add(cur);
return;
}
if (open < max) //选择1添加左括号,并注意判断左括号的数量
backtrack(ans, cur+"(", open+1, close, max);
if (close < open) //选择2添加右括号 左右括号是数量最终一定相同
backtrack(ans, cur+")", open, close+1, max);
}
}
思路2:闭合数
为了枚举某些内容,我们通常希望将其表示为更容易计算的不相交子集的总和。
考虑有效括号序列 S
的闭包数:至少存在index> = 0
,使得 S[0], S[1], ..., S[2*index+1]
是有效的。 显然,每个括号序列都有一个唯一的闭包号。 我们可以尝试单独列举它们。对于每个闭合数 c
,我们知道起始和结束括号必定位于索引 0
和 2*c + 1
。然后两者间的 2*c
个元素一定是有效序列,其余元素一定是有效序列。
这种思路有点看不懂。。。。。先记在这里
代码:
class Solution {
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList();
if (n == 0) {
ans.add("");
} else {
for (int c = 0; c < n; ++c)
for (String left: generateParenthesis(c)) //这个是什么意思,是循环c左边的字符串么?
for (String right: generateParenthesis(n-1-c))
ans.add("(" + left + ")" + right);
}
return ans;
}
}