LeetCode括号生成
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1输出:["()"]
思路分析:
这个题是典型地用深度优先搜索(或是递归)+回溯的方式去遍历和生成各个结果。可以在脑海里想象一颗树,一开始是什么也没有,后来分了两个支:一个是(,另一个是),很明显后者因为不合法,会被我们检测并淘汰。而前者又分成两个支:()和((,而这两者再分别往下分支……最终我们判断括号对数到达我们要求时,就将结果保存即可。
具体实现起来其实有很多方法,不过整体思路都差不多。可以根据注释来理解。
代码:
class Solution(object):
def generateParenthesis(self, n):
cangku = {'(':n,')':n} #我们定义一个“仓库”,根据给定的n,先存放了n个(和n个)。
#后续我们生成括号的时候,就从仓库里拿,如果仓库里数量变成0了,就说明不能拿了,生成完了。当然反过来也一样的,即当生成的某一类括号到达限制后就停止。只不过我感觉用“仓库”的概念好理解一些。
has={'(':0,')':0}#has,代表我们现在已经生成的字符串有的括号情况
res=[]#res存储最终生成结果
def di(s):#定义递归函数di,参数s代表当前生成的括号字符串
if has['(']==n and has[')']==n:#如果此时已有的括号数都到达n
res.append(s) #添加进结果,直接结束
#其他情况时,(即括号数不足n)
if has['(']==has[')']: #如果此时左右括号数量一样,则说明只能添加左括号了
if cangku['(']>0: #先看看仓库里还有没有左括号,有的话就拿出来用
cangku['(']-=1#仓库里左括号数量-1
has['(']+=1#现有的左括号+1
di(s+'(')#送入递归
cangku['(']+=1#回溯的精髓,送入递归后,状态还原。
has['(']-=1
if has['(']>has[')']:#如果左括号数大于右括号数,则添加左和右都可
if cangku['(']>0: #添加左
cangku['(']-=1
has['(']+=1
di(s+'(')
cangku['(']+=1
has['(']-=1
if cangku[')']>0:#添加右
cangku[')']-=1
has[')']+=1
di(s+')')
cangku[')']+=1
has[')']-=1
#可以发现,对于右括号多于左括号的情况,就默认不处理了,因为这类情况已经没必要进行下一步的分支了,自动淘汰。
di('')#执行di函数,参数一开始为空字符串。
return res
小结
回溯的作用是因为在此时这个节点,可能要做多个选择,所以我们选择A之后,马上就要退回当前节点的状态,才能去选择B,这样才能保证不乱。不过这个题的回溯写法我感觉也不是很标准,还是以解决问题为主了。一般正常的回溯就是 di(has,choose)形式:两个参数一个是现有的状态,另一个是选择列表。虽然本质思想都是一样的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了