news 2026/8/1 11:23:35

力扣 22. 括号生成:C++ 实现回溯 + 动态规划双解法,面试高频题必掌握

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣 22. 括号生成:C++ 实现回溯 + 动态规划双解法,面试高频题必掌握

在算法面试中,括号生成问题是经典的字符串组合题型,力扣第 22 题「括号生成」更是高频考点。题目要求给定括号对数 n,生成所有有效的括号组合,看似简单却能深度考察对回溯、动态规划等核心算法思想的掌握。今天用 C++ 实现两种最优解法,兼顾代码简洁性和可读性,小白也能轻松理解!

一、题目核心分析

  • 输入:括号对数 n(1≤n≤8)
  • 输出:所有有效括号组合(有效 = 左右括号数量相等 + 每一步左括号数≥右括号数)
  • 示例:n=3 时,输出 ["((()))","(()())","(())()","()(())","()()()"]

关键约束:生成过程中必须保证「左括号未用完时可加左括号,右括号数量小于左括号时可加右括号」,这是避免无效组合的核心。

二、解法一:回溯算法(最优解)

回溯本质是「试探 - 回退」的深度优先搜索,通过剪枝避免无效路径,效率极高,也是 C++ 面试中最推荐的写法。

核心思路

  1. 定义辅助递归函数,参数包含当前组合字符串、左括号使用数、右括号使用数和结果集(引用传递)。
  2. 终止条件:左右括号均用完(字符串长度 = 2n),将当前组合加入结果集。
  3. 剪枝逻辑:
    • 左括号未用完(left < n):可添加左括号,递归继续。
    • 右括号少于左括号(right < left):可添加右括号,递归继续。

代码实现(C++)

#include <vector> #include <string> using namespace std; class Solution { public: vector<string> generateParenthesis(int n) { vector<string> result; backtrack("", 0, 0, n, result); return result; } private: // 回溯函数:当前字符串、左括号数、右括号数、总对数、结果集 void backtrack(string current, int left, int right, int n, vector<string>& result) { // 终止条件:字符串长度达到2n(左右括号均用完) if (current.size() == 2 * n) { result.push_back(current); return; } // 左括号未用完,可添加左括号 if (left < n) { backtrack(current + '(', left + 1, right, n, result); } // 右括号数量小于左括号,可添加右括号(保证有效) if (right < left) { backtrack(current + ')', left, right + 1, n, result); } } };

优势

  • 时间复杂度 O (4ⁿ/√n):符合卡特兰数时间规模,无多余无效路径。
  • 空间复杂度 O (n):递归栈深度最多为 2n,额外空间仅用于存储结果。
  • C++ 特性适配:通过引用传递 result 避免拷贝开销,string 拼接高效简洁。

三、解法二:动态规划(递推思想)

通过拆解子问题,利用已解决的 n-1 对括号组合推导 n 对的结果,适合喜欢递推思路的同学,C++ 中 vector 的嵌套存储让子问题结果复用更方便。

核心思路

  • 状态定义:dp [i] 表示 i 对括号的所有有效组合(vector<string>类型)。
  • 递推公式:dp [i] = "(" + dp [p] + ")" + dp [q],其中 p+q = i-1(p≥0,q≥0)。
    • 解释:每新增 1 对括号,可视为在 p 对括号外包裹 1 对括号,再拼接 q 对括号。
  • 初始状态:dp [0] = {""}(0 对括号对应空字符串)。

代码实现(C++)

#include <vector> #include <string> using namespace std; class Solution { public: vector<string> generateParenthesis(int n) { // dp[i]存储i对括号的所有有效组合 vector<vector<string>> dp(n + 1); dp[0] = {""}; // 初始状态:0对括号为空字符串 // 递推计算1到n对括号的组合 for (int i = 1; i <= n; ++i) { // 遍历所有可能的p(q = i-1 - p) for (int p = 0; p < i; ++p) { int q = i - 1 - p; // 拼接所有p和q的组合 for (const string& strP : dp[p]) { for (const string& strQ : dp[q]) { dp[i].push_back("(" + strP + ")" + strQ); } } } } return dp[n]; } };

优势

  • 逻辑直观:通过子问题拼接得到结果,无需递归,避免栈溢出风险。
  • 可复用性强:dp 数组存储了所有小于 n 的结果,便于后续扩展(如统计组合数、筛选特定格式组合)。
  • C++ 容器适配:vector 的动态扩容特性完美适配不同规模的结果存储。

四、两种解法对比与实战建议

解法时间复杂度空间复杂度适用场景
回溯算法O(4ⁿ/√n)O(n)面试首选(代码简洁)
动态规划O(4ⁿ/√n)O(4ⁿ/√n)需复用子问题结果时

实战建议:

  1. 面试中优先写回溯算法,C++ 代码仅需一个辅助函数,逻辑清晰易解释。
  2. 若面试官追问非递归解法或优化方向,再补充动态规划思路。
  3. 核心约束「左括号数≥右括号数」是有效组合的关键,务必牢记。
  4. 代码可直接运行:包含必要头文件和类结构,LeetCode 提交即可通过。

五、总结

括号生成问题的核心是「有效约束」和「组合遍历」,C++ 实现中,回溯算法利用递归 + 剪枝高效筛选路径,动态规划借助 vector 容器实现子问题递推。两种解法均围绕卡特兰数的数学本质,掌握后可举一反三解决同类组合问题(如合法括号计数、括号匹配检查等)。

建议先手动模拟 n=2、n=3 的生成过程,再对照代码理解逻辑,最后自己动手实现一遍。如果有优化思路或其他解法,欢迎在评论区交流~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 22:06:08

springboot天天篮球馆管理系统-计算机毕业设计源码58402

摘 要 本论文设计并实现了基于Spring Boot框架的“天天”篮球馆管理系统&#xff0c;旨在为篮球馆提供一个高效、便捷的管理平台&#xff0c;提升场馆运营管理的效率与用户体验。系统采用MySQL数据库进行数据存储&#xff0c;并使用Java编程语言实现后台业务逻辑&#xff0c;支…

作者头像 李华
网站建设 2026/7/31 7:30:50

MusicFreeDesktop音质提升全攻略:从模糊到清晰的三步操作

MusicFreeDesktop音质提升全攻略&#xff1a;从模糊到清晰的三步操作 【免费下载链接】MusicFreeDesktop 插件化、定制化、无广告的免费音乐播放器 项目地址: https://gitcode.com/gh_mirrors/mu/MusicFreeDesktop 还在为音乐细节模糊而烦恼&#xff1f;明明下载了无损音…

作者头像 李华
网站建设 2026/7/30 11:57:36

Oracle数据库迁移

简单谈谈本人对Oracle数据库的理解 话不多说直接开始 第一步&#xff1a;将原始数据库导出 方式1&#xff08;推荐&#xff09;&#xff1a;使用Data Pump --创建文件路径 create or replace directory 路径名 as C:\backup --根据情况自定义--执行导出命令 expdp 用户名/密…

作者头像 李华
网站建设 2026/8/1 3:16:13

Java毕设项目:基于SpringBoot的高校学生奖项管理系统基于springboot高校奖助学金系统(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/31 19:10:10

Wan2.2-T2V-A14B支持剪纸艺术动态展开过程模拟

Wan2.2-T2V-A14B支持剪纸艺术动态展开过程模拟 在数字内容创作的浪潮中&#xff0c;我们正见证一场从“静态图像”到“动态叙事”的跃迁。过去需要数小时手工拍摄、后期合成的传统艺术表现形式&#xff0c;如今只需一句话——比如&#xff1a;“一张红色宣纸缓缓展开&#xff0…

作者头像 李华
网站建设 2026/8/1 10:39:22

12.电阻电容电感选型

一、电阻 1、选型依据 阻值:电阻值; 封装:常用封装0201,0402,0603,0805,1206,1812等&#xff1b; 功耗:1/16W,1/10W,1/8W,1/4W,1/2W,1W,2W,3W等&#xff1b; 精度:1%&#xff0c;5%等。 2、选型方法 ①、优先考虑阻值&#xff0c;对于不常见的阻值&#xff0c;可以通过电阻的…

作者头像 李华