给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这一题归类在回溯算法下,很容易就想到了回溯算法,我写出来的版本:
class Solution:
def __init__(self):
self.ans = []
def generateParenthesis(self, n: int) -> List[str]:
self.generate(n*2,0,'')
return self.ans
def generate(self,deep,left_num,s):
if left_num < 0 or deep < 0:
return
if deep == 0 and left_num == 0:
# good ans
self.ans.append(s)
self.generate(deep-1,left_num+1,s+'(')
self.generate(deep-1,left_num-1,s+')')
首先我用一个deep代表现在还能插入多少个符号,初始值为 n*2。当deep==0的时候也就意味着不能再插入符号了。
这里的left_num代表左括号的数量-右括号的数量,由于我是从左往右一个一个插入符号,在任何情况下不可能出现右括号数量比左括号多的,也就是说一旦出现了left_num<0,就可以跳出递归。
所以递归结束条件就得出来了。
而当deep0以及left_num0,说明这是一个正确的答案。
别人家的leetcode
我的代码简洁有余而速度不足,思路清晰但是毕竟不够精巧。
补充我认为比较优雅的解法,出处已经标明在结尾。
反思
首先,面向小白:什么是动态规划?在此题中,动态规划的思想类似于数学归纳法,当知道所有 i<n 的情况时,我们可以通过某种算法算出
i=n 的情况。 本题最核心的思想是,考虑 i=n 时相比 n-1 组括号增加的那一组括号的位置。思路
具体思路如下: 当我们清楚所有 i<n 时括号的可能生成排列后,对与 i=n 的情况,我们考虑整个括号排列中最左边的括号。
它一定是一个左括号,那么它可以和它对应的右括号组成一组完整的括号 “( )”,我们认为这一组是相比 n-1 增加进来的括号。那么,剩下 n-1 组括号有可能在哪呢? 【这里是重点,请着重理解】
剩下的括号要么在这一组新增的括号内部,要么在这一组新增括号的外部(右侧)。既然知道了 i<n 的情况,那我们就可以对所有情况进行遍历: “(” + 【i=p时所有括号的排列组合】 + “)” +【i=q时所有括号的排列组合】 其中 p + q = n-1,且p q均为非负整数。 事实上,当上述 p 从 0 取到 n-1,q 从n-1 取到 0 后,所有情况就遍历完了。
代码: 具体代码如下:(时间击败百分之 95,内存击败百分之 99.65)【p.s. 实测并没有这么高了…】
class Solutin: def generateParenthesis(self, n: int) -> List[str]: if n == 0: return [] total_l = [] total_l.append([None]) total_l.append(["()"]) for i in range(2,n+1): # 开始计算i时的括号组合,记为l l = [] for j in range(i): #遍历所有可能的括号内外组合 now_list1 = total_l[j] now_list2 = total_l[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) total_l.append(l) return total_l[n] ```
作者:yuyu-13
链接:https://leetcode-cn.com/problems/two-sum/solution/zui-jian-dan-yi-dong-de-dong-tai-gui-hua-bu-lun-da/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
重点:动态规划。
将i<n的情况都记录下来,然后可以认为:
n的情况是 n-1情况的扩展。具体扩展就是加一对括号,那么只要基于之前的【可行情况】加一对就好了。