题目描述:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
无思路,参考答案中的解释
方法一:暴力法
思路
我们可以生成所有 2^{2n}22n 个 '('
和 ')'
字符构成的序列。然后,我们将检查每一个是否有效。
算法
为了生成所有序列,我们使用递归。长度为 n
的序列就是 '('
加上所有长度为 n-1
的序列,以及 ')'
加上所有长度为 n-1
的序列。
为了检查序列是否为有效的,我们会跟踪平衡
,也就是左括号的数量减去右括号的数量的净值。如果这个值始终小于零或者不以零结束,该序列就是无效的,否则它是有效的。
代码
class Solution(object):
def generateParenthesis(self, n):
def generate(A = []):
if len(A) == 2*n:
if valid(A):
ans.append("".join(A))
else:
A.append('(')
generate(A)
A.pop()
A.append(')')
generate(A)
A.pop()
def valid(A):
bal = 0
for c in A:
if c == '(': bal += 1
else: bal -= 1
if bal < 0: return False
return bal == 0
ans = []
generate()
return ans
方法二:回溯法
思路和算法
只有在我们知道序列仍然保持有效时才添加 '('
or ')'
,而不是像方法一那样每次添加。我们可以通过跟踪到目前为止放置的左括号和右括号的数目来做到这一点,
如果我们还剩一个位置,我们可以开始放一个左括号。 如果它不超过左括号的数量,我们可以放一个右括号。
代码
class Solution(object):
def generateParenthesis(self , N):
ans = []
def backtrack(S = '',left = 0,right = 0):
if len(S) == 2*N:
ans.append(S)
if left < N:
backtrack(S+'(',left+1,right)
if right <left:
backtrack(S+')',left,right+1)
backtrack()
return ans