python-leetcode 48.括号生成

题目:

数字n代表生成括号的对数,设计一个函数,用于生成所有可能并且有效的括号组合。


方法一:回溯

可以生成所有 2**2n 个 '(' 和 ')' 字符构成的序列,然后检查每一个是否有效即可

为了生成所有序列,我们可以使用递归。长度为 n 的序列就是在长度为 n−1 的序列前加一个 '(' 或 ')'。

为了检查序列是否有效,遍历这个序列,并使用一个变量 balance 表示左括号的数量减去右括号的数量。如果在遍历过程中 balance 的值小于零,或者结束时 balance 的值不为零,那么该序列就是无效的,否则它是有效的。

可以只在序列仍然保持有效时才添加 '(' 或 ')',通过跟踪到目前为止放置的左括号和右括号的数目来做到这一点,如果左括号数量不大于 n,我们可以放一个左括号。如果右括号数量小于左括号的数量,我们可以放一个右括号。

python 复制代码
class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        ans=[] #列表,用于存储所有有效的括号组合
        def backtrack(S,left,right):  #递归回溯函数,当前构造的括号序列,当前左括号的数目,当前右括号的数目
            if len(S)==2*n:  #长度达到合法括号的序列
                ans.append(''.join(S))#列表 S 变成字符串,加入列表中
                return
            if left<n:  #当左括号数目不达标时
                S.append("(")
                backtrack(S,left+1,right)  #加入左括号后继续构造
                S.pop()#递归返回后,将最后添加的 ( 移除,恢复原状(回溯)
            if right<left:  #只有 right < left 时,才能添加 ),确保括号序列合法
                S.append(")") #加了一个 ) 之后继续尝试构造
                backtrack(S,left,right+1)
                S.pop() # 将最后添加的 ) 移除,恢复原状
        backtrack([],0,0)
        return ans

时间复杂度:O(​4*n/n**1/2​),在回溯过程中,每个答案需要 O(n) 的时间复制到答案数组中

空间复杂度:O(n)


方法二:按括号序列的长度递归

任何一个括号序列都一定是由 '(' 开头,并且第一个 '(' 一定有一个唯一与之对应的 ')',每一个括号序列可以用 (a)b 来表示,其中 a 与 b 分别是一个合法的括号序列(可以为空)。

生成所有长度为 2n 的括号序列,我们定义一个函数 generate(n) 来返回所有可能的括号序列。那么在函数 generate(n) 的过程中:

需要枚举与第一个 '(' 对应的 ')' 的位置 2i+1

递归调用 generate(i) 即可计算 a 的所有可能性

递归调用 generate(n−i−1) 即可计算 b 的所有可能性

遍历 a 与 b 的所有可能性并拼接,即可得到所有长度为 2n 的括号序列

为了节省计算时间,在每次 generate(i) 函数返回之前,把返回值存储起来,下次再调

用 generate(i) 时可以直接返回,不需要再递归计算

python 复制代码
class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        if n==0:  #没有括号对
                return [""]
        ans=[]
        for c in range(n): #让c在0到n-1之间遍历,表示把 n 对括号分成两部分,左部分:c 对括号;右部分n - 1 - c 对括号
            for left in self.generateParenthesis(c):#递归调用自己,求出 c 对括号的所有可能组合,并把结果赋值给 left,相当于生成左部分括号的所有可能情况
                for right in self.generateParenthesis(n - 1 - c):#生成右部分括号的所有可能情况
                    ans.append('({}){}'.format(left,right)) #负责把 left 和 right 组合
        return ans

时间复杂度:O(​4*n/n**1/2​)

空间复杂度:O(​4*n/n**1/2​)此方法除答案数组外,中间过程中会存储与答案数组同样数量级的临时数组,是所需要的空间复杂度。

源自力扣官方题解

相关推荐
江畔柳前堤3 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore4 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考6 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX6 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面7 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号7 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽7 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI7 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者9 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者9 小时前
【征程6】校准量化中HistogramObserver解析
算法