问题描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例1
输入:n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]
示例2
输入:n = 1
输出:[“()”]
提示
- 1 <= n <= 8
思路分析
我们可以利用回溯法生成所有可能的括号组合。由于在组合过程中,我们需要保证每个右括号都有对应的左括号,因此得到的组合都是有效的。同时,我们通过限制左括号和右括号的数量,可以确保生成的组合中左括号和右括号的数量都是正确的。最终,返回的结果列表即为所有可能的有效括号组合。
- 定义一个函数
generateParenthesis
,接收一个整数参数n
,表示生成括号的对数。函数的返回值是一个字符串列表,包含所有可能的并且有效的括号组合。 - 创建一个空列表
result
,用于保存结果。 - 调用辅助函数
backtrack
,传入参数result
、空字符串""
、左括号的数量和右括号的数量都为0,以及目标括号对数n
。 - 在
backtrack
函数中,首先检查当前的组合长度是否达到了目标长度(2 * n)。如果是,则将当前组合添加到结果列表result
中,并返回。 - 如果当前左括号的数量小于目标括号对数
n
,则可以添加一个左括号。递归调用backtrack
函数,在当前组合后面添加一个左括号,并将左括号计数增加1。 - 如果当前右括号的数量小于当前左括号的数量,说明我们可以添加一个右括号。递归调用
backtrack
函数,在当前组合后面添加一个右括号,并将右括号计数增加1。 - 递归结束后,就可以得到所有可能的并且有效的括号组合。
- 返回结果列表
result
。
代码分析
generateParenthesis
方法:这个方法是对外的接口函数,接收一个整数参数n
,表示生成括号的对数。方法的返回值是一个字符串列表,包含所有可能的并且有效的括号组合。result
变量:这是一个空列表,用于保存最终的结果。backtrack
方法:这是一个辅助函数,用于生成有效的括号组合。它接收五个参数:result
、current
、open_count
、close_count
和n
。
result
:保存结果的列表。current
:表示当前的组合。open_count
:表示已经添加的左括号数量。close_count
:表示已经添加的右括号数量。n
:目标括号对数。
if len(current) == 2 * n:
:这个条件判断用于判断当前组合的长度是否达到了目标长度,即2 * n。如果达到了目标长度,说明得到了一个有效的括号组合,将其添加到结果列表result
中,并返回。if open_count < n:
:这个条件判断用于判断当前左括号的数量是否小于目标括号对数n
。如果是,则可以在当前组合后面添加一个左括号。递归调用backtrack
函数,将当前组合current + "("
、左括号数量open_count + 1
、右括号数量close_count
和目标括号对数n
作为参数。if close_count < open_count:
:这个条件判断用于判断当前右括号的数量是否小于当前左括号的数量。如果是,则可以在当前组合后面添加一个右括号。递归调用backtrack
函数,将当前组合current + ")"
、左括号数量open_count
、右括号数量close_count + 1
和目标括号对数n
作为参数。
通过以上递归和回溯的过程,可以生成所有可能的并且有效的括号组合。最终,返回结果列表
result
。
完整代码
class Solution(object): def generateParenthesis(self, n): """ :type n: int :rtype: List[str] """ result = [] # 初始化结果列表,用于保存最终的括号组合 self.backtrack(result, "", 0, 0, n) # 调用回溯函数生成括号组合 return result # 返回结果列表 def backtrack(self, result, current, open_count, close_count, n): if len(current) == 2 * n: # 如果当前组合的长度达到目标长度2*n result.append(current) # 将当前组合添加到结果列表中 return # 结束当前回溯路径 if open_count < n: # 如果左括号数量小于目标括号对数n self.backtrack(result, current + "(", open_count + 1, close_count, n) # 在当前组合后面添加一个左括号,递归调用回溯函数 if close_count < open_count: # 如果右括号数量小于当前左括号数量 self.backtrack(result, current + ")", open_count, close_count + 1, n) # 在当前组合后面添加一个右括号,递归调用回溯函数
详细分析
前
方法是对外的接口函数,接收一个整数n
,代表括号对的数量。它首先初始化一个空列表result
,用于保存最终的结果。然后调用backtrack
方法,开始递归生成括号组合。backtrack
方法是一个辅助函数,用于实现递归和回溯算法来生成所有可能的括号组合。它接收五个参数:result
用于保存结果的列表,current
当前的括号组合字符串,open_count
左括号的数量,close_count
右括号的数量,n
目标括号对的数量。- 首先,在
backtrack
方法中,判断当前组合的长度是否达到目标长度(2 * n),如果是,则表示已经生成了一个有效的括号组合,将当前组合添加到结果列表result
中,并结束当前回溯路径。 - 如果左括号的数量小于目标括号对数
n
,说明还可以添加左括号,执行以下操作:
- 在当前组合字符串
current
的末尾添加一个左括号,表示选择了一个左括号。 - 递归调用
backtrack
方法,并传入更新后的参数:新的组合字符串、左括号数量加一、右括号数量不变。
- 如果右括号的数量小于当前左括号的数量,说明还可以添加右括号,执行以下操作:
- 在当前组合字符串
current
的末尾添加一个右括号,表示选择了一个右括号。 - 递归调用
backtrack
方法,并传入更新后的参数:新的组合字符串、左括号数量不变、右括号数量加一。
- 通过递归和回溯的过程,不断生成括号组合,直到得到所有可能的并且有效的括号组合。
- 最终,将结果列表
result
返回作为最终的输出。
这个算法的关键在于理解递归和回溯的思想。通过不同的选择(添加左括号或右括号),生成所有可能的括号组合,并通过判断条件来确保生成的组合是有效的。递归函数在每一步都会做出选择并递归调用自身,直到满足结束条件,然后回溯到上一步,继续进行下一种选择,直到尝试完所有的选择。通过这种方式,遍历所有可能的情况,得到最终的结果。
运行效果截图
调用
solution = Solution() n = 3 n1 = 1 print(solution.generateParenthesis(n)) print(solution.generateParenthesis(n1))
运行结果
完结