解法:1、n代表的是左括号和右括号的个数,最后生成的字符串的长度为2n,首先想到的就是枚举的方法,假设有2n的数组,每一个格子都有两种情况,填做括号还是右括号。
2、很明显上面的方法是不符合常理的,因为做括号和右括号都是有限制,当n为3的时候,不会出现((((((的情况,所以当我们进行递归的时候,就需要进行判断,当左括号用完的时候就要停止,称为剪枝。
3、动态规划解法,当看到有和没有,放和不放的时候,可以考虑动态规划的解法。这里有个leetcode上面的讲解动态规划解法,
4、我补充一下我的见解和理解(其实是我没有很快理解他文章的意思),帮助你从不同的思路上理解。
首先,面向小白:什么是动态规划?在此题中,当知道所有 i=n-1 的情况时,我们可以通过对之前的情况来算出 i=n 的情况。
本题最核心的思想是,考虑 i=n 时相比 n-1 组括号增加的那一组括号的位置。(ps:建议参考本博客动态规划篇,从简单的斐波拉契数列,背包问题开始)
【思路】:
如果你看了本博客的动态规划内容或者有一定写动态规划的经验的话,会明白对于动态规划问题的我们要找的就是最优子问题,也就是递推公式。
假设一种情况,我们已经知道了i=n-1时括号的可能生成排列后,对于i=n的情况,我们只需要把这个完整的“()”放到n-1的排列中就可以了。有两种情况,一个是这对新加的括号,左括号和右括号里面加入一些在n-1的括号排列组合,或者是这对新加的括号,添加到排列组合中。
举一个栗子,当n=2的时候,排列组合符合条件的是这两种,"(())","()()",那我们把“()”放在其中会出现哪几种情况,"((()))","(())()","(())()","()(())","()()()",
由于能力有限,不知道用什么数据结构来进行很好的插入。暂无代码,希望有看到相同思路的战友,或者能写出来的,留言一下让我好好学习一下,辛苦了。
#第二种方法
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
#list输出的是最后结果,如n等于3,那么list里面就是装的所有可能性
self.list =[]
#left和right里面存的是括号使用了多少
self._gen(0, 0, n, "")
return self.list
def _gen(self, left, right, n, result):
if left ==n and right ==n:
self.list.append(result)
if left<n:
self._gen(left+1, right, n, result+"(")
if left > right and right < n:
self._gen(left, right+1, n, result+")")
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
if n == 0:
return []
total_l = []
total_l.append([None]) # 0组括号时记为None
total_l.append(["()"]) # 1组括号只有一种情况
for i in range(2,n+1): # 开始计算i组括号时的括号组合
l = []
for j in range(i): # 开始遍历 p q ,其中p+q=n-1 , j 作为索引
now_list1 = total_l[j] # p = j 时的括号组合情况
now_list2 = total_l[i-1-j] # q = (i-1) - j 时的括号组合情况
for k1 in now_list1:
for k2 in now_list2:
if k1 == None:
k1 = ""
if k2 == None:
k2 = ""
el = "(" + k1 + ")" + k2
l.append(el) # 把所有可能的情况添加到 l 中
total_l.append(l) # l这个list就是i组括号的所有情况,添加到total_l中,继续求解i=i+1的情况
return total_l[n]