描述
该题来自于力扣第22题
数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
提示:
1 <= n <= 8
分析
要生成有效的括号,第一个字符必然是左括号(,那么第二个有可能是(或者),以n=3为例,生成有效括号的过程应该如下:

可以看出是一颗二叉树,二叉树的每条路径对应着一个有效括号组合,所以关键在于如何生成这颗树。思路也很简单,第一层已经确定只能是(,由于n=3表示最多可以有3个(,所以第二层可能是(,也可能是),那第三层如何确定呢?
假如第二层选择的是(,由于左括号的个数为2,小于n,所以第三层也可能是(或者);如果第二层选择的是),一样的分析。
第三层如果选择的是(,这是左括号的个数已经等于n,所以第四层只能添加)了。
综上分析可知,假设当前层已有的左括号个数为left,已有右括号个数为right,若left<n,则当前层可以为(,同时若right<left,那么当前层也可以是);否则结束,所有括号添加完毕。
树生成后,可以使用深度优先遍历所有的路径得到结果,这里可以采用递归的写法,注意一点就是遍历到叶子结点后,需要回溯到初始状态,具体可以看算法说明。
算法
- 初始化
n,left=right=0,以及路径s="" - 递归函数
f(n, left, rihgt, s) - 进入递归主体,如果
len(s)==2*n,表明s已经包含了所有括号,添加到结果列表中,并退出函数 - 如果
left < n,这时添加(,进入函数f(n, left+1, right, s+"("),这里s+"("写在函数形参内,刚好避免回溯时s不受影响,s的变化至于该路径的前面所有层有关。 - 如果
right < n,这时添加),进入函数f(n, left, right, s+")")
具体算法执行步骤可以这么理解:
首先一直添加(直到无法添加为止,然后添加)直到无法添加为止,即一直遍历树的左节点,然后开始回溯,这时s为((())),根据算法会回溯到s="(("即第二层的左节点也是步骤4的结尾,之后进入步骤5。依次下去。
代码
python3
1 | class Solution: |
c++
1 | class Solution { |
java
1 | class Solution { |