每日一题——括号生成

题解

给定 n 对括号,要求编写一个函数生成所有合法的括号组合。合法的括号组合必须满足每一对括号中的左括号必须先于右括号,并且括号数量必须平衡。

题目描述

输入:

  • 一个整数 n,表示括号的对数,满足 0 ≤ n ≤ 10 0 \leq n \leq 10 0n10

输出:

  • 返回一个包含所有合法括号组合的字符串数组。

示例1

输入:

1

输出:

["()"]

示例2

输入:

2

输出:

["(())", "()()"]

题解思路

这个问题是一个典型的递归回溯问题。我们可以通过递归来生成所有可能的括号组合。具体步骤如下:

  1. 用递归函数生成括号的组合。
  2. 每次递归调用时,有两个选择:
    • 如果左括号还没有用完,就添加一个左括号 '('
    • 如果右括号的数量小于左括号的数量,且右括号还没有用完,就添加一个右括号 ')'
  3. 当左右括号的数量都达到了 n 时,表示一个合法的组合已经完成,将其加入结果数组。

时间复杂度和空间复杂度

  • 时间复杂度:O( 2 n 2^n 2n),因为每一层递归有两种选择(添加左括号或右括号)。
  • 空间复杂度:O( n n n),由于递归调用栈的深度是 n,每次递归都在 2n 长度的字符串上操作。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>/*** 深度优先搜索(DFS)函数,用于生成所有有效的括号组合* * @param left 左括号的数量* @param right 右括号的数量* @param ret 存储所有生成的括号组合的数组* @param path 当前路径,即当前生成的括号组合* @param n 括号对数* @param returnSize 当前已生成的括号组合数量*/
void DFS(int left, int right, char **ret, char* path, int n, int *returnSize) {// 如果左括号和右括号的数量都等于 n,说明生成了一个有效的括号组合if (left == n && right == n) {// 为当前括号组合分配内存,长度为 2n + 1(包括字符串终止符)ret[*returnSize] = malloc(sizeof(char) * (2 * n + 1));if (ret[*returnSize] == NULL) {printf("Memory allocation failed\n");exit(1);}// 将当前路径复制到结果数组中for (int i = 0; i < 2 * n; i++) {ret[*returnSize][i] = path[i];}ret[*returnSize][2 * n] = '\0'; // 添加字符串终止符// 增加已生成的括号组合数量(*returnSize)++;return;}// 如果左括号的数量小于 n,可以添加一个左括号if (left < n) {path[left + right] = '('; // 在当前路径中添加左括号DFS(left + 1, right, ret, path, n, returnSize); // 递归调用,继续生成}// 如果右括号的数量小于左括号的数量且小于 n,可以添加一个右括号if (right < left && right < n) {path[left + right] = ')'; // 在当前路径中添加右括号DFS(left, right + 1, ret, path, n, returnSize); // 递归调用,继续生成}
}/*** 主函数,生成所有有效的括号组合* * @param n 括号对数* @param returnSize 返回的括号组合数量* @return 存储所有有效括号组合的数组*/
char** generateParenthesis(int n, int *returnSize) {// 预分配足够大的空间存储结果,这里假设最多有 2000 种组合char** ret = (char**)malloc(sizeof(char*) * 2000);if (ret == NULL) {printf("Memory allocation failed\n");exit(1);}*returnSize = 0; // 初始化返回的括号组合数量为 0// 为当前路径分配内存,长度为 2n + 1(包括字符串终止符)char* path = (char*)malloc(sizeof(char) * (2 * n + 1));if (path == NULL) {printf("Memory allocation failed\n");exit(1);}// 调用 DFS 函数生成所有有效的括号组合DFS(0, 0, ret, path, n, returnSize);// 释放当前路径的内存free(path);return ret;
}

解析

  1. DFS函数的递归逻辑:

    • DFS(left, right, ret, str, n, returnSize)是递归的核心函数,leftright 分别表示已使用的左括号和右括号数量。
    • 如果leftright都达到了n,就将当前字符串str(存放括号组合)存入ret数组。
    • 如果left < n,我们可以继续添加左括号。
    • 如果right < left,我们可以继续添加右括号。
  2. 空间分配:

    • 结果数组ret被分配了2000个空间,可以容纳所有合法组合(理论上可能达到O(4^n)个组合,但实际上不会达到这么多)。
    • 每个合法的括号组合是一个长度为2n的字符串,因此str的长度是2n
  3. 返回值:

    • ret返回存放合法括号组合的数组,returnSize返回合法组合的数量。

总结

通过递归的方式,我们能够高效地生成所有合法的括号组合。递归回溯方法简洁而直观,适合解决此类组合生成的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

π 的奥秘:如何用有理数逼近无理数?

本文将围绕有理数、无理数、连续统以及它们之间的深刻联系展开讨论&#xff0c;并结合具体的数学理论如康托尔区间套定理、戴德金分割、柯西施瓦茨不等式等&#xff0c;进行简要探讨 由于本文并未深入探讨&#xff0c;可能存在部分不严谨的地方&#xff0c;也欢迎各位进行纠正…

图书管理项目(spring boot + Vue)

想要该项目的话&#xff0c;就 jia 我&#xff0c;并在评论区给我说一下&#xff0c;只需要1元&#xff0c;我把整个项目发给你 jia微&#xff1a;18439421203&#xff08;名字叫&#xff1a;Bingo&#xff09; 运行图片&#xff1a;

131,【2】 攻防世界 catcat-new

进入靶场 &#x1f431; 点击图片时发现url处很可疑 想到文件读取 ../app.py # 导入 os 模块&#xff0c;用于与操作系统进行交互&#xff0c;例如文件操作、路径操作等 import os # 导入 uuid 模块&#xff0c;用于生成通用唯一识别码&#xff0c;常用于生成随机的密钥 imp…

NO.12十六届蓝桥杯备战|关系操作符|操作符连用|浮点数比较|练习2道(C++)

关系操作符 关系操作符介绍 ⽤于⽐较的表达式&#xff0c;称为“关系表达式”&#xff08;relational expression&#xff09;&#xff0c;⾥⾯使⽤的运算符就称为“关 系运算符”&#xff08;relational operator&#xff09;&#xff0c;主要有下⾯6个。 运算符描述>⼤…

.NET Web-静态文件访问目录浏览

一、Web根目录访问 创建wwwroot文件夹app.UseStaticFiles(); // 启⽤静态⽂件中间件url/路径 进行访问 二、Web根目录之外的文件 app.UseStaticFiles(new StaticFileOptions {FileProvider new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath,&qu…

【漏洞复现】Casbin get-users 账号密码泄漏漏洞

免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删除。…

PPDock:复旦大学团队研发的蛋白质-配体“盲对接“技术

PPDock: Pocket Prediction-Based Protein−Ligand Blind Docking 发表于Journal of Chemical Information and Modeling&#xff0c;第一作者为 Jie Du&#xff0c;通讯作者为 Manning Wang&#xff0c;研究团队来自复旦大学。该研究提出一种新的基于口袋预测的蛋白质 - 配体盲…

中间件-安装Minio-集成使用(ubantu-docker)

目录 1、安装docer 2、运行以下命令拉取MinIO的Docker镜像 3、检查当前所有Docker下载的镜像 4、创建目录 5、创建Minio容器并运行 6、SDK操作 FileUploader.java 1、安装docer 参考这篇&#xff1a;Linux安装Docker 2、运行以下命令拉取MinIO的Docker镜像 docker pull…

使用 Notepad++ 编辑显示 MarkDown

Notepad 是一款免费的开源文本编辑器&#xff0c;专为 Windows 用户设计。它是替代记事本&#xff08;Notepad&#xff09;的最佳选择之一&#xff0c;因为它功能强大且轻量级。Notepad 支持多种编程语言和文件格式&#xff0c;并可以通过插件扩展其功能。 Notepad 是一款功能…

Java 大视界 -- 区块链赋能 Java 大数据:数据可信与价值流转(84)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【Android开发】Android Studio汉化

前言 该插件是官方支持插件&#xff0c;未对任何软件进行修改和破解 Android Studio 是基于 IntelliJ IDEA 社区版开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于Android应用程序的开发。以下是为什么 Android Studio 能使用 IntelliJ IDEA 插件的原因&am…

七、I2C通信读取LM75B温度

7.1 概述 I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种同步、多主从、串行通信协议&#xff0c;由飞利浦公司开发&#xff0c;主要用于短距离通信&#xff0c;尤其在集成电路之间。 7.1.1 主要特点 两线制&#xff1a;仅需SDA&#xff08;数据线&#xff09;…

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层 1. 两个元素实现 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>纯 CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层</titl…

微信小程序医院挂号系统

第3章 系统设计 3.1系统体系结构 系统的体系结构非常重要&#xff0c;往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为微信小程序医院挂号系统&#xff0c;属于开放式的平台&#xff0c;所以在管理端体系结构中采用B/s。B/s结构抛弃了固…

开源堡垒机 JumpServer 社区版实战教程:一步步构建企业安全运维环境

文章目录 开源堡垒机 JumpServer 社区版实战教程&#xff1a;一步步构建企业安全运维环境一、访问JumpServer1.1 登录1.2 功能模块1.3 系统设置1.3.1 基本设置1.3.2 邮件设置 二、用户管理2.1 场景2.2 创建用户2.3 用户登录密码重置 三、资产管理3.1 准备工作3.2 登录控制台3.3…

小红书八股面经一份(JAVA开发)

1. zmysql索引结构 mysql索引底层采用的是b树的结构&#xff0c;一开始mysql的索引采用的是b树的结构&#xff0c;当数据量达到一定程度的时候&#xff0c;b树存在深度过大的问题&#xff0c;那么磁盘io次数就会飞速上升&#xff0c;导致查询效率慢。b树就很好的解决了这个问题…

redis 缓存击穿问题与解决方案

前言1. 什么是缓存击穿?2. 如何解决缓存击穿?怎么做?方案1: 定时刷新方案2: 自动续期方案3: 定时续期 如何选? 前言 当我们使用redis做缓存的时候,查询流程一般是先查询redis,如果redis未命中,再查询MySQL,将MySQL查询的数据同步到redis(回源),最后返回数据 流程图 为什…

路由过滤方法与常用工具

引言 在前面我们已经学习了路由引入&#xff0c;接下来我们就更进一步来学习路由过滤 前一篇文章&#xff1a;重发布&#xff1a;路由引入&#xff08;点击即可&#xff09; 路由过滤 定义&#xff1a;路由器在发布或者接收消息时&#xff0c;可能需要对路由信息进行过滤。 作用…

网络分析工具—WireShark的安装及使用

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;常被网络管理员、开发人员和安全专家用来捕获和分析网络数据包。它支持多种网络协议&#xff0c;能够帮助用户深入理解网络流量、诊断网络问题以及进行安全分析。 Wireshark 的主要功能 数据包捕获与分析&#xff1a; …

anolis os 8.9安装jenkins

一、系统版本 # cat /etc/anolis-release Anolis OS release 8.9 二、安装 # dnf install -y epel-release # wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo # rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.…