问题描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。
示例:
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
解题
方法一:暴力破解
(1)生成所有序列
利用递归生成所有序列,下图有助于理解生成过程:ter)
通过递归生成序列的过程就是对树的遍历过程。

注意到这颗树的根节点是一个左括号,这样做直接省去了第一个括号是右括号这个错误的情况
(2)检查是否有效
对一个生成的序列从左到右遍历的时候左括号的个数必须始终大于等于又括号的个数这个序列才符合要求。比如"())("就不符合要求。
另外对一个生成的序列从左到右遍历的时候只要左括号的数量大于n那么这个序列也不符合要求。
(3)如何进行递归
实际上(1)和(2)都是为了用递归的思路解决这个问题做的铺垫,这道题可以用递归的原因是:生成长度为2n的字符数组等价于生成第一个字符加上生成剩下的2n-1个字符。参考3道题彻底搞定:套路解决递归问题中的方法我们对这道题进行分析:
递归三部曲:
- 终止条件:生成了长度为2n的括号组且符合生成要求
- 本级递归需要做什么:往括号组里面添加或者删除左括号或者右括号,用来生成新的括号组
- 返回值是什么:所生成的符合要求的所有可能的括号组
具体代码如下:
class Solution:
def generate_parenthesis(self, n):
def generate(A):
# 终止条件(START)
if len(A) == 2*n:
if valid(A):
ans.append("".join(A))
# 终止条件(END)
# 本级递归需要做的事(START)
else:
A.append('(')
generate(A)
A.pop()
A.append(')')
generate(A)
A.pop()
# 本级递归需要做的事(END)
def valid(A):
bal = 0
for c in A:
if c == '(':
bal += 1
else:
bal -= 1
if bal > n or bal < 0:
return False
return bal == 0
ans = []
generate([])
# 返回值
return ans
if __name__ == '__main__':
solution = Solution()
result = solution.generate_parenthesis(3)
print(result)
方法二:回溯法
方法二其实是对方法一的改进,因为方法一中直到生成长度为2n的括号组之后才去判断这个括号组的有效性,但实际上在括号组生成的过程中当右括号的数量大于左括号的数量时这个括号组就已经无效了,所以可以在中间进行判断从而改进算法。
LeetCode官方的程序:
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
ans = []
def backtrack(S, left, right):
if len(S) == 2 * n:
ans.append(''.join(S))
return
if left < n:
S.append('(')
backtrack(S, left+1, right)
S.pop()
if right < left:
S.append(')')
backtrack(S, left, right+1)
S.pop()
backtrack([], 0, 0)
return ans
本文详细解析了LeetCode括号生成问题的两种解法:暴力破解与回溯法。介绍了如何通过递归生成所有可能的括号组合,并在过程中检查其有效性,避免无效组合的生成。
630

被折叠的 条评论
为什么被折叠?



