当前位置: 首页 > article >正文

LeetCode【0022】括号生成

本文目录

  • 1 中文题目
  • 2 求解方法:回溯法
    • 2.1 方法思路
    • 2.2 Python代码
    • 2.3 复杂度分析
  • 3 题目总结

1 中文题目

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

示例:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
输入:n = 1
输出:["()"]

提示:

  • 1 ≤ n ≤ 8 1 \leq n \leq 8 1n8

2 求解方法:回溯法

2.1 方法思路

方法核心

  • 使用回溯法生成所有可能的括号组合,回溯算法的约束条件:
    • 任意时刻,已使用的右括号数量不能超过已使用的左括号数量
    • 左括号和右括号的总数量都不能超过n
    • 当左右括号都用完时,得到一个有效组合
  • 通过左右括号数量的关系确保生成的括号组合有效
  • 使用剪枝策略避免生成无效的括号组合

实现步骤

  • 初始化
    • 创建空的结果列表,设置初始左右括号数量为n
    • 调用回溯函数,从空字符串开始构建
    • 递归过程中根据条件选择添加左括号或右括号
    • 当左右括号都用完时,将当前字符串加入结果列表
  • 括号添加规则
    • 只要还有左括号,就可以添加左括号(left > 0)
    • 只有当右括号剩余数量大于左括号时,才能添加右括号(right > left)
  • 递归终止条件
    • 当left和right都为0时,找到一个有效组合
    • 将current加入result列表
    • 返回上一层递归
  • 有效性保证
    • 任何时刻已使用的右括号数量不能超过已使用的左括号数量
    • 通过right > left的判断条件来保证
    • 左右括号的使用数量都不能超过初始值n
  • 结果返回
    • 回溯完成后,result列表包含所有有效组合
    • 直接返回result列表作为最终结果

方法示例

输入:n = 2
过程演示:

# 初始状态:left=2, right=2, current=""
└── ""
    
# 第一层递归:可以添加左括号
└── "("  (left=1, right=2)
    
# 第二层递归:可以添加左括号或右括号
├── "((" (left=0, right=2)  # 添加左括号
└── "()" (left=1, right=1)  # 添加右括号
    
# 第三层递归:
├── "(()" (left=0, right=1)  # 从"(("添加右括号
└── "()(" (left=0, right=1)  # 从"()"添加左括号
    
# 第四层递归:
├── "(())" (left=0, right=0)  # 从"(()"添加右括号
└── "()()" (left=0, right=0)  # 从"()("添加右括号

最终结果:["(())", "()()"]

2.2 Python代码

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        # 结果列表,存储所有有效的括号组合
        result = []
        
        def backtrack(left: int, right: int, current: str):
            """
            回溯函数
            left: 剩余可用的左括号数量
            right: 剩余可用的右括号数量
            current: 当前已生成的括号字符串
            """
            # 当左右括号都用完时,找到一个有效组合
            if left == 0 and right == 0:
                result.append(current)
                return
            
            # 只要还有剩余的左括号,就可以添加左括号
            if left > 0:
                backtrack(left - 1, right, current + "(")
            
            # 只有当剩余的右括号数量大于剩余的左括号数量时
            # 才可以添加右括号,这样确保括号组合有效
            if right > left:
                backtrack(left, right - 1, current + ")")
        
        # 初始调用回溯函数,开始时左右括号都有n个
        backtrack(n, n, "")
        return result

2.3 复杂度分析

  • 时间复杂度: O ( 4 n / n ) O(4^n/\sqrt{n}) O(4n/n ),这是第n个卡特兰数的时间复杂度
    • 生成的括号组合数量是卡特兰数
    • 每个组合的生成需要O(n)的时间
  • 空间复杂度:O(n):
    • 递归栈的深度最大为2n
    • 存储结果的空间不计入空间复杂度
    • 每个递归层级使用常数空间

3 题目总结

题目难度:中等
数据结构:字符串数组
应用算法:回溯法


http://www.kler.cn/a/392591.html

相关文章:

  • uniCloud云对象调用第三方接口,根据IP获取用户归属地的免费API接口,亲测可用
  • 2024/11/13 英语每日一段
  • 九州未来再度入选2024边缘计算TOP100
  • 使用 start-local 脚本在本地运行 Elasticsearch
  • 《MYSQL45讲》kill不掉的线程
  • MyBatisPlus 用法详解
  • 腾讯云产品推荐----域名的使用
  • 【时间之外】IT人求职和创业应知【31】
  • 万字长文解读深度学习——ViT、ViLT、DiT
  • 【go从零单排】Text Templates
  • 单体架构VS微服务架构
  • 高阶函数全解析(定义、应用 -- 函数柯理化 反柯理化 发布订阅模式 观察者模式)
  • 执行npm run build -- --report后,生产report.html文件是什么?
  • kafka是如何处理数据乱序问题的?
  • Java代码操作ZooKeeper(使用原生 ZooKeeper 客户端库)
  • UE5 设置Sequence播完后返回起始位置
  • hadoop报错找不到主类
  • 苹果低价版Vision Pro 推迟至2027年发布:XR领域的变局与挑战
  • TypeORM在Node.js中的应用
  • 缓存雪崩问题及解决方法
  • C# 异步Task异常处理和堆栈追踪显示
  • iOS 18.1,未公开的新功能
  • OpenStack讲解和实例
  • 2022年蓝桥杯JavaB组 省赛 题目解析(含AC_Code)
  • 【达梦数据库】MYSQL迁移到DM字符集转换问题-UTF8mb4|转UTF8(UTF8mb3)
  • Dubbo 3.x源码(25)—Dubbo服务引用源码(8)notify订阅服务通知更新