问题:
# 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
#
#
#
# 示例 1:
#
#
# 输入:n = 3
# 输出:["((()))","(()())","(())()","()(())","()()()"]
实现:
# leetcode submit region begin(Prohibit modification and deletion) class Solution: def generateParenthesis(self, n: int) -> List[str]: res = [] def _recursion(res, n, left, right, s): if len(s) == 2 * n: res.append(s) return if left < n: _recursion(res, n, left + 1, right, s + '(') if left > right: _recursion(res, n, left, right + 1, s + ')') _recursion(res, n, 0, 0, '') return res # leetcode submit region end(Prohibit modification and deletion)
方法二:动态规划
动态规划分三步走:
第一步:定义状态 dp[i]:使用 i 对括号能够生成的组合
第二步:状态转移方程:
1)i 对括号的一个组合,在 i-1 对括号的基础上得到,这是 状态转移方程 的基础;
2)i 对括号的一个组合,一定以左括号 ( 为开始。所以可以想象成在一堆左括号中插入右括号,以此得到所有组合
枚举的方式就是枚举左括号 ( 和右括号)中间可能的合法的括号对数,而剩下的合法的括号对数在与第一个左括号( 配对的右括号的后面,这就用到了以前的状态
状态转移方程:
dp[i] = “(” + dp[可能的括号对数] + “)” + dp[剩下的括号对数]
整理得:
dp[i] = “(” + dp[j] + “)” + dp[i-1-j] , j = 0, 1, …, i - 1
第三步:思考初始状态和输出:
初始状态:因为我们需要 0 对括号这种状态,因此状态数组 dp 从 0 开始,0 个括号当然就是 [""]
输出:dp[n]
def generateParenthesis(n): if not n: return [] dp = [None for _ in range(n+1)] dp[0] = [""] for i in range(1, n+1): tmp = [] for j in range(i): left = dp[j] right = dp[i-1-j] for s1 in left: for s2 in right: tmp.append("(" + s1 + ")" + s2) dp[i] = tmp return dp[n]