(day28)leecode——有效括号

news2025/2/26 6:30:13

描述

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 8

leecode题解灵茶山艾府 

枚举填左括号还是右括号

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        ans = []  # 初始化一个空列表,用于存储最终生成的所有有效括号组合
        m = n * 2  # 计算所有括号的总长度,因为一个有效的括号组合由n个左括号和n个右括号组成,所以长度为n*2
        path = [''] * m  # 初始化一个长度为m的空字符列表,用于构建括号组合

        # 定义一个深度优先搜索(DFS)函数,用于生成括号组合
        # i 表示当前填入括号的位置
        # open 表示已经放入的左括号数量
        # i-open 表示已经放入的右括号数量
        def dfs(i: int, open: int) -> None:
            if i == m:  # 如果当前填入的位置已经达到总长度m,说明已经生成了一个完整的括号组合
                ans.append(''.join(path))  # 将当前生成的括号组合加入结果列表
                return
            if open < n:  # 如果左括号数量还未达到n个,可以继续放入左括号
                path[i] = '('  # 在当前位置放入一个左括号
                dfs(i + 1, open + 1)  # 递归调用DFS,位置后移一位,左括号数量加一
            if i - open < open:  # 如果右括号数量少于左括号数量,可以放入右括号
                path[i] = ')'  # 在当前位置放入一个右括号
                dfs(i + 1, open)  # 递归调用DFS,位置后移一位,左括号数量不变

        dfs(0, 0)  # 从位置0开始,初始左括号数量为0
        return ans  # 返回生成的所有有效括号组合
整体分析
  • 初始化数据结构

    • 创建一个空列表 ans,用于存储所有有效的括号组合。
    • 计算括号组合的总长度 m,即 n * 2
    • 创建一个长度为 m 的空字符列表 path,用于构建括号组合。
  • 深度优先搜索函数定义

    • 定义一个递归函数 dfs(i, open)
      • i 表示当前正在填入括号的位置。
      • open 表示当前已经放入的左括号数量。
    • i 等于 m 时,即已经填入了 m 个位置,将当前 path 中的括号组合转换为字符串并加入到 ans 中。
  • 递归生成括号组合

    • 如果 open 小于 n,可以在当前位置 i 放入一个左括号 '(',递归调用 dfs(i + 1, open + 1)
    • 如果 i - open 小于 open,即右括号数量少于左括号数量,可以在当前位置 i 放入一个右括号 ')',递归调用 dfs(i + 1, open)
  • 启动递归

    • 调用 dfs(0, 0),从位置0开始,初始左括号数量为0,开始生成所有有效的括号组合。
  • 返回结果

    • 返回存储在 ans 列表中的所有有效括号组合。

 

复杂度分析

 
时间复杂度:分析回溯问题的时间复杂度,有一个通用公式:路径长度×搜索树的叶子数。对于本题,它等于 O(n⋅C(2n,n))。但由于左右括号的约束,实际上没有这么多叶子,根据 Catalan 数,只有  个叶子节点,所以实际的时间复杂度为 O(C(2n,n))。此外,根据阶乘的 Stirling 公式,时间复杂度也可以表示为 
空间复杂度:O(n)。返回值的空间不计入。

枚举下一个左括号的位置

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        ans = []  # 用于存储所有合法的括号组合
        path = []  # 用于记录当前生成的括号组合的路径
        
        def dfs(i: int, balance: int) -> None:
            # i:当前正在处理的括号的位置
            # balance:当前路径中的左括号数量减去右括号数量
            
            if len(path) == n:
                # 如果路径长度等于 n,则说明当前路径已经形成了一对合法括号
                s = [')'] * (n * 2)  # 初始化括号数组,全用右括号
                for j in path:
                    s[j] = "("  # 将路径中的位置设为左括号
                ans.append(''.join(s))  # 形成完整的括号组合并添加到答案中
                return  # 结束当前递归
            
            # 遍历可能的右括号位置
            for close in range(balance + 1):
                path.append(i + close)  # 将当前的括号位置添加到路径中
                dfs(i + close + 1, balance - close + 1)  # 递归调用,更新位置和余额
                path.pop()  # 撤销当前位置,回溯到上一个状态
        
        dfs(0, 0)  # 初始调用
        return ans  # 返回所有合法括号组合
 整体分析
  • 初始化:创建一个列表 ans 来存储所有合法的括号组合,同时创建一个空列表 path 用于记录当前生成的括号路径。

  • 定义递归函数

    • 参数:函数 dfs 接受两个参数:i 表示当前处理的位置,balance 表示当前路径中左括号和右括号的差值(即平衡度)。
    • 检查完成状态:如果当前路径的长度等于 n,说明当前路径代表一个完整的合法括号组合。接着根据 path 中记录的位置构建这个组合的字符串,并将其添加到结果列表 ans 中。
  • 生成组合

    • 遍历可能的右括号位置,根据当前的平衡度确定可能的位置。
    • 将当前位置添加到 path 中,并递归调用 dfs 函数来继续生成下一个位置的括号组合。
    • 递归返回后,从 path 中移除当前位置,以便回溯到之前的状态,尝试其他可能的组合。
  • 开始递归:从初始状态调用 dfs 函数,开始生成括号组合。

  • 返回结果:所有合法的括号组合生成完成后,返回存储这些组合的列表 ans

Leecode题解小笨蛋

 

 一个满二叉树,我们只需要DFS所有节点即可。先把所有组合给生成出来,即DFS所有节点。把不符合的给过滤掉结束DFS。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频转场SDK,高效集成,提升视频制作效率

传统的视频制作方式往往受限于单一的转场效果&#xff0c;难以在瞬息万变的市场中脱颖而出。美摄科技&#xff0c;作为视频处理技术的领航者&#xff0c;以其革命性的视频转场SDK&#xff0c;为企业视频创作带来了前所未有的创意与效率飞跃。 重塑转场艺术&#xff0c;激发创意…

el-table 表格列宽自适应

思路&#xff1a;获取当前列的最长数据和表头名称比较&#xff0c;取大值赋值给宽度。 效果图 自适应前 自适应后 自适应方法 // col 里面包含了表头字段和名称&#xff0c;list 是表格数据 columnWidth(col, list) {let prop col.prop, lab col.lab;let width 90; // 设…

数据结构——双向链表及其总结

1.概述 链表根据是否带头、是否双向、是否循环可以分为八种&#xff0c;双向链表是典型的带头双向循环链表。 双向链表的结构可以表示为下&#xff1a; struct ListNode {int data;struct ListNode* next;struct ListNode* prev; } 2.双向链表的实现过程及其解析 双向链表…

Redis 内存淘汰策略

Redis 作为一个内存数据库&#xff0c;必须在内存使用达到配置的上限时采取策略来处理新数据的写入需求。Redis 提供了多种内存淘汰策略&#xff08;Eviction Policies&#xff09;&#xff0c;以决定在内存达到上限时应该移除哪些数据。

如何理解Java的内存模型

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~ 阅读指南 开篇说明一、内存相关基础了解1.1 硬件的内存架构1.2 缓存一致性问题1.3 内存模型的出现二、Java内存模型2.1 组成部分2.2 模型特性2.4 As-if-serial语义与Happens-bef…

【2024蓝桥杯/C++/B组/前缀总分】

题目 代码 #include<bits/stdc.h> using namespace std;// 定义常量N为210&#xff0c;用于数组的大小 const int N 210; // 声明n为整型变量&#xff0c;用于存储字符串的数量 int n; // 声明一个字符串数组str&#xff0c;大小为N&#xff0c;用于存储字符串 string …

pda条码扫描手持机,数据采集器助力景区售检票

随着科技的发展&#xff0c;景区也在往信息化方向发展&#xff0c;景区为了提升售票、检票入园效率&#xff0c;可采用pda条码扫描手持机售检票系统。pda条码扫描手持机是一种便携式的检票设备&#xff0c;可以随时随地使用。配备5.5寸高清大屏,1440*720分辩率&#xff0c;多点…

安防监控视频融合汇聚平台EasyCVR创建新用户时没有摄像机权限,是什么原因?

国标GB28181/RTSP/ONVIF视频管理系统EasyCVR视频汇聚平台&#xff0c;是一个具备高度集成化、智能化的多协议接入视频监控汇聚管理平台&#xff0c;拥有远程视频监控、录像、云存储、录像检索与回放、语音对讲、云台控制、告警、平台级联等多项核心功能。EasyCVR安防监控视频系…

docker笔记5-数据卷

docker笔记5-数据卷 一、数据卷1.1 定义1.2 本质1.3 特点 二、使用数据卷三、案例2.1 安装Mysql 四、匿名挂载和具名挂载4.1 匿名挂载4.2 具名挂载 五、三种挂载方式 一、数据卷 1.1 定义 Docker 容器数据卷是一个可用于存储数据的特殊目录&#xff0c;存在于一个或多个容器的…

免费【2024】springboot 出租车管理网站的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

unity2D游戏开发15自我防御

创建子弹 Ammo类来表示自子弹 创建一个GameObject,并命名为AmmoObject 将Ammo.png拖入Object中 属性设置,点击apply 将SpriteRenderer组件添加到AmmoObject,将Sorting Layer设置为Characters,并将Sprite属性设置为Ammo 将CircleCollider2D添加到AmmoObject。确保选中Is Tr…

【C++高阶】哈希的应用(封装unordered_map和unordered_set)

✨ 世事漫随流水&#xff0c;算来一生浮梦 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&…

KubeSphere部署:(三)MySQL安装

MySQL没有什么特殊的&#xff0c;这里记录一下部署过程(本文示例中安装的版本为5.7.29)。步骤大致如下&#xff1a; 拉取docker镜像 -> 标记并推送至私有harbor -> 创建有状态负载 -> 创建服务 一、拉取镜像&#xff0c;并推送至私有harbor # 拉取镜像 docker pull …

PP氮气柜的特点和使用事项介绍

PP材质&#xff0c;全称为聚丙烯&#xff0c;是一种热塑性塑料&#xff0c;具有质轻、强度高、耐化学腐蚀性好、无毒无味、耐热性佳等优点。它在众多塑料材料中脱颖而出&#xff0c;特别是在需要耐腐蚀和长期使用的应用中&#xff0c;表现尤为出色。 PP材质具有优秀的化学稳定性…

Loadrunner12 回放脚本查看接口响应数据

1、如下图所示&#xff0c;回放脚本后&#xff0c;点击快照-http数据-点击需要查看的接口-点击Json视图&#xff0c;最后点击响应正文&#xff0c;即可查看接口的响应数据

生信初学者教程(癌症转录组学):手把手教你如何发生信文章

网址 生信初学者教程&#xff08;癌症转录组学&#xff09; : https://bioinformatic-learner.github.io/BCT-page/ 提供了预览版本。 该教程包含从开题、数据下载、数据分析、结果解读、串联结果和撰写文章等等&#xff0c;是一份非常好的生信初学者发文章的好材料。 出发点…

【Linux】UDP 协议

目录 1. UDP 协议2. UDP 协议的特点:3. UDP 协议的格式4. UDP 的缓冲区基于UDP的应用层协议 1. UDP 协议 UDP (User Datagram Protocol) 是一种面向数据报的传输层协议, 是传输层的重要协议之一; UDP协议提供了一种无连接, 不可靠的数据传输服务; 适用于要求源主机以恒定速率…

响应式建站陶瓷企业类公司网站源码系统 带完整的安装代码包以及搭建部署教程

系统概述 响应式建站陶瓷企业类公司网站源码系统是一款专为陶瓷企业设计的网站建设解决方案。该系统采用响应式设计&#xff0c;能够自动适应不同设备的屏幕尺寸&#xff0c;为用户提供一致的浏览体验。无论用户是通过电脑、平板还是手机访问网站&#xff0c;都能获得清晰、美…

html+css 实现3D分层悬停按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

太牛了!恭喜7位毕业急录、评职晋升作者,2天录用,1-8天见刊!

本周投稿推荐 SCI&EI • 4区“水刊”&#xff0c;纯正刊&#xff08;来稿即录&#xff09; • CCF-B类&#xff0c;IEEE一区-Top&#xff08;3天初审&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; 知网&#xff08;CNKI&#xff09;、谷歌学术 …