题目描述:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
思路:
方法一:暴力法:枚举出所有的括号组合,再判断其是否有效
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
def generate(seq=[]):
if len(seq) == 2 * n:
if valid(seq):
ans.append("".join(seq))
else:
seq.append('(')
generate(seq)
seq.pop()
seq.append(')')
generate(seq)
seq.pop()
def valid(seq):
# 通过左右括号的数量是否匹配判断序列是否有效
left = 0
for c in seq:
if c == '(':
left += 1
else:
left -= 1
# left 小于 0 说明出现了右括号在左括号之前
if left < 0:
return False
return left == 0
ans = []
generate()
return ans
方法二:回溯法(其实也是一种DFS):
暴力方法的过程中会生成很多很显然不正确的序列,例如’((((((’,但从左右括号数量上看就不符合。为了减少不必要的序列城市,将检查有效性提前,只有当序列当前有效时才继续添加’(‘或者’)’。
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
def backtrack(prefix, left, right):
if len(prefix) == 2 * n:
res.append(prefix)
return
# 控制左括号的数量,避免出现'(((((('的情况
if left < n:
backtrack(prefix + '(', left + 1, right)
# 控制右括号的数量
if right < left:
backtrack(prefix + ')', left, right + 1)
backtrack('', 0, 0)
return res
方法三:动态规划法(官方题解称为闭合数):
假如我们已经知道 n=i 时的所有有效括号组合,用 S 表示其中任意一个组合,那么n=i+1 时的所有有效括号应该如何计算?是