https://leetcode.com/problems/generate-parentheses/description/
题意:给一个数n,表示n对括号,求所有配对的组合
思路1:暴力。先生成所有括号的组合,然后逐个检测是否满足条件。
重点是生成所有的组合(长度为2*n,每个位置有左括号和右括号两种可能,共2^2n种情况),用递归。
别人的解释是“All sequences of length n is just ‘(’ plus all sequences of length n-1, and then ‘)’ plus all sequences of length n-1.”。
然而我自己的理解是对每个位置,先放一个'('
,然后弹出,改为放一个')'
(或者顺序反过来也行,结果一样),把每个位置都处理一遍。
检测是否符合就比较简单了,看左右是否配对即可。
class Solution:
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
def generate(A = []): #生成所有组合。初始为空list
if len(A) == 2 * n:
if valid(A):
res.append("".join(A))
else:
A.append('(') #A后面加一个'('
generate(A) #递归
A.pop() #弹出'('
A.append(')') #A后面加一个')'
generate(A) #递归
A.pop() ##弹出')'
def valid(s): #验证一个字符串是否符合
bal = 0
for i in s:
if i == '(':
bal += 1
else:
bal -= 1
if bal < 0:
return False
return bal == 0
res = []
generate()
return res
思路2:回溯。不是先生成所有组合,而是用递归回溯的方法生成所有合法的组合。“We can do this by keeping track of the number of opening and closing brackets we have placed so far.”
已知左括号先出现,且个数为0~n,因此先对左括号进行递归到底,条件为left < n
(用left记录左括号数)。然后对右括号递归,条件为右括号数(用right记录)比左括号数少,即right < left
。
递归出口为生成的串A长度增长到2n时。
class Solution:
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
def generate(A = '', left = 0, right = 0):
if len(A) == 2 * n:
res.append("".join(A))
return
if left < n: #先对左括号递归
generate(A + '(', left + 1, right)
if right < left: #再对右括号递归
generate(A + ')', left, right+1)
res = []
generate()
return res