22.括号生成
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
**Python most votes solution: **
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
def generate(p, left, right, parens=[]):
if left: generate(p + '(', left-1, right)
if right > left: generate(p + ')', left, right-1)
if not right: parens += p,
return parens
return generate('', n, n)
分析:
- 算法用到了DFS(深度优先搜索);
- 假定输入n = 3,则整个DFS的过程如下:
最终会产生5组符合题意的括号组合。
-
算法用p来记录当前已经生成的括号,并在不同轮次的递归之间传递;用parens来保存每一次DFS的最终结果,产生parens的标志是right == 0(此时右括号全部用完)。
-
初始时,p为空,用left来记录左括号剩余的数目,用right来记录右括号剩余的数目。
-
算法通过以下两个途径来保证生成的括号的有效性:
(1)算法设定左括号的优先级大于右括号(即在同等条件下,总是优先使用左括号,然后再使用右括号),这是通过left和right的判断顺序来实现的:算法设定先对left进行判断;当left不符合要求时才会判断right;
(2)在对right进行判断时,用到的并不是
if right
或者if right >= left
,而是if right > left
,这样做的原因是:- 若用
if right
,则结果会漏掉某些情况而且可能会出错; - 若用
if right >= left
,则当right抵达边界(right = 0)时,算法不会停止,而是会在已经正确的结果上添加一个额外的右括号从而导致结果出错。
结合以上两种讨论,只有
if right > left
是唯一正确的,而且这种判断会保证右括号的数目永远不会比左括号多(考虑right抵达边界的情况),从而保证了结果的正确性。 - 若用