数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
有效括号组合需满足:左括号必须以正确的顺序闭合。
不考虑时间限制的情况,一般都会想到暴力解法(递归和回溯)。
我们先来看回溯+剪枝,采用DFS(深度优先搜索)的方法,做减法,构造树形结构图,需要产生分支,左右括号数目需要大于0,当左右括号的数目为0时,递归终止。左括号大于0时,拼接左括号,右括号数目不能小于左括号,不然无法产生分支(也就是括号无法成对)。贴上大佬的一个图解:作者:liweiwei1419 链接
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
def dfs(l,r,s):
if l == 0 and r == 0:
res.append(s)
if l > 0:
dfs(l-1,r,s + '(')
if r > l:
dfs(l,r-1,s + ')')
s = ''
dfs(n,n,s)
return res
也可以采用做加法,计算左右括号的使用数目来构造树形结构。一个合法的括号序列,任意前缀都是左括号数目≥右括号数目,此时才能继续加入右括号匹配。图解同上述链接。
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
def dfs(l,r,s):
if l == n and r == n:
res.append(s)
if l < r:#做加法时右边需要小于左边括号才会产生分支
return #return语句用于退出函数,向调用方返回一个表达式。
#return在不带参数的情况下(或者没有写return语句),默认返回None
if l < n:
dfs(l+1,r,s + '(')
if r < n:
dfs(l,r+1,s + ')')
s = ''
dfs(0,0,s)
return res
还可以使用插入方法,在有效括号()的基础上,在括号内外位置任意插入第二个括号,依此类推,直至第n个括号,利用set去除重复的括号。
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = set(['()'])
for i in range(n-1):
tmp = set()
for s in res:
tmp.update(set([s[:j] + '()' + s[j:] for j in range(len(s))]))#更新字典中的键值
res = tmp
return list(res)