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

Python面试宝典第25题:括号生成

题目

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

        备注:1 <= n <= 8。

        示例 1:

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

        示例 2:

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

递归法

        使用递归法求解此问题的基本思想是:将生成有效括号序列的问题分解为更小的子问题。对于每一对括号,我们都可以看作是在已有的有效括号序列基础上,或者在其前后分别添加一个左括号和右括号。为了保证序列的有效性,我们需要确保任何时候左括号的数量都不少于右括号的数量。因此,可以采用递归的方式,逐步构建所有可能的序列。使用递归法求解本题的主要步骤如下。

        1、定义递归函数。函数接受两个参数,left 表示还可以使用的左括号数量,right 表示还可以使用的右括号数量,以及当前已经构造的括号序列curr_str。

        2、递归终止条件。当left和right都为0时,说明当前序列是一个有效的括号组合,将其加入结果列表。

        3、递归生成左括号。如果还有左括号可用(left > 0),则在当前序列后添加一个左括号,然后递归调用自身,减小left的计数。

        4、递归生成右括号。如果右括号的数量少于等于左括号(right <= left),则不能添加右括号,因为这会导致序列无效。否则,在当前序列后添加一个右括号,然后递归调用自身,减小right的计数。

        5、回溯。在每次递归调用返回后,撤销之前的选择,即回到上一层继续尝试其他可能性。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def generate_brackets_by_recursion(n):def backtrack(left, right, curr_str, result):if left == 0 and right == 0:result.append(curr_str)returnif left > 0:backtrack(left - 1, right, curr_str + '(', result)if right > left:backtrack(left, right - 1, curr_str + ')', result)result = []backtrack(n, n, '', result)return resultprint(generate_brackets_by_recursion(3))
print(generate_brackets_by_recursion(1))

总结

        递归法求解本题的时间复杂度主要取决于生成的括号组合的数量。对于n对括号,有效的括号组合数量遵循卡特兰数,其公式为C_n = (1/(n+1)) * (2n choose n)。卡特兰数的增长速度非常快,大约是 4^n / (sqrt(pi*n)*n^(3/2))。因此,时间复杂度为 O(C_n),即:O(4^n / sqrt(n))。空间复杂度主要由递归栈的深度决定,最坏情况下,递归栈的深度为2n,故空间复杂度为O(n)。

        递归法特别适合括号生成类问题,因为它能自然地表达出问题的结构,即通过逐步构建解的空间树来寻找所有可能的解。然而,当n接近上限(比如:n=8)时,生成的组合数量会非常庞大,这可能会对程序的执行时间和内存使用提出较高的要求。因此,在实际应用中需要考虑递归的深度和效率问题。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 反序列化靶机serial
  • ThreadLocal:线程本地变量的作用与应用
  • 8G内存的Mac够用吗 ?苹果电脑内存满了怎么清理?可以有效地管理和优化你的Mac电脑内存,确保设备运行流畅
  • 开源跨平台SQL编辑器:Beekeeper Studio
  • Python中的异常处理除了Try语句,你还会啥?
  • 安装jdk和tomcat
  • KVM+GFS分布式文件系统构建KVM高可用
  • Vue3+TypeScript+printjs 实现标签批量打印功能
  • Spingboot请求tcp 方式
  • 写一个图片裁剪的js,JavaScript图片裁剪插件PlusCropper
  • 【数值计算方法】数值积分微分-python实现-p2
  • volatile 关键字的两层语义
  • jEasyUI 扩展编辑器
  • 读零信任网络:在不可信网络中构建安全系统06授权
  • springboot的表现层/控制层controller开发
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【技术性】Search知识
  • CentOS 7 防火墙操作
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • leetcode386. Lexicographical Numbers
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • opencv python Meanshift 和 Camshift
  • PAT A1120
  • SOFAMosn配置模型
  • Vue小说阅读器(仿追书神器)
  • 初探 Vue 生命周期和钩子函数
  • 从0实现一个tiny react(三)生命周期
  • 分布式熔断降级平台aegis
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 给第三方使用接口的 URL 签名实现
  • 基于遗传算法的优化问题求解
  • 入门级的git使用指北
  • 入手阿里云新服务器的部署NODE
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 学习使用ExpressJS 4.0中的新Router
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​Spring Boot 分片上传文件
  • # wps必须要登录激活才能使用吗?
  • # 达梦数据库知识点
  • #大学#套接字
  • (23)Linux的软硬连接
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (译) 函数式 JS #1:简介
  • (转)Linux整合apache和tomcat构建Web服务器
  • .describe() python_Python-Win32com-Excel
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • /boot 内存空间不够