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

【Leetcode hot 100】22.括号生成

问题链接

22.括号生成

问题描述

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

示例 1:

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

示例 2:

输入:n = 1
输出:[“()”]

提示:

  • 1 <= n <= 8

问题解答

一、回溯法(推荐)

核心思路
回溯法通过「尝试生成括号 + 剪枝无效路径」实现:

  1. 状态跟踪:记录当前括号字符串、已使用的左括号数量、已使用的右括号数量。
  2. 终止条件:当字符串长度等于 2*n(n 对括号共 2n 个字符)时,将其加入结果列表。
  3. 递归逻辑
    • 优先添加左括号:若左括号数量 < n,可继续加左括号(保证后续有机会补右括号)。
    • 谨慎添加右括号:若右括号数量 < 左括号数量(避免出现 ()) 等无效组合),可加右括号。
  4. 剪枝:通过上述条件直接排除无效路径,无需生成所有组合后再筛选,效率更高。

代码实现

import java.util.ArrayList;
import java.util.List;class Solution {// 存储最终结果的列表private List<String> result = new ArrayList<>();public List<String> generateParenthesis(int n) {// 初始调用:空字符串、左括号0个、右括号0个backtrack("", 0, 0, n);return result;}/*** 回溯递归函数* @param current 当前构建的括号字符串* @param left 已使用的左括号数量* @param right 已使用的右括号数量* @param n 目标括号对数*/private void backtrack(String current, int left, int right, int n) {// 终止条件:字符串长度达到 2n(括号生成完成)if (current.length() == 2 * n) {result.add(current);return;}// 1. 尝试添加左括号:左括号未用完时可加if (left < n) {backtrack(current + "(", left + 1, right, n);}// 2. 尝试添加右括号:右括号数量 < 左括号数量时可加(避免无效组合)if (right < left) {backtrack(current + ")", left, right + 1, n);}}
}

复杂度分析

  • 时间复杂度:O(4ⁿ / √n),生成的有效组合数为「卡特兰数」Cₙ,其渐近复杂度为 4ⁿ / √n。
  • 空间复杂度:O(n),递归栈深度最大为 2n(字符串长度),且无额外存储(除结果列表外)。

二、动态规划法

核心思路
动态规划通过「子问题的解构建当前问题的解」,核心是找到状态转移规律:

  1. 状态定义dp[i] 表示生成 i 对括号的所有有效组合列表。
  2. 基础 casedp[0] = [""](0 对括号只有空字符串一种情况)。
  3. 状态转移:对于 i 对括号,可拆分为「左半部分 j 对 + 中间 1 对 + 右半部分 i-j-1 对」,即:
    • dp[i] = "(" + dp[j] + ")" + dp[i-j-1](其中 j ∈ [0, i-1]
    • 例如 i=2 时,j=0()()j=1(()),故 dp[2] = ["()()", "(())"]

代码实现

import java.util.ArrayList;
import java.util.List;class Solution {public List<String> generateParenthesis(int n) {// dp[i] 存储 i 对括号的所有有效组合List<List<String>> dp = new ArrayList<>();// 基础 case:0 对括号只有空字符串dp.add(new ArrayList<>());dp.get(0).add("");// 从 1 对括号递推到 n 对括号for (int i = 1; i <= n; i++) {dp.add(new ArrayList<>()); // 初始化 dp[i]// j 表示左半部分的括号对数(0 ≤ j < i)for (int j = 0; j < i; j++) {// 遍历左半部分的所有组合(dp[j])for (String left : dp.get(j)) {// 遍历右半部分的所有组合(dp[i-j-1])for (String right : dp.get(i - j - 1)) {// 拼接:(左半)右半dp.get(i).add("(" + left + ")" + right);}}}}return dp.get(n); // 返回 n 对括号的组合}
}

复杂度分析

  • 时间复杂度:O(4ⁿ / √n),与回溯法一致,需生成所有卡特兰数对应的组合。
  • 空间复杂度:O(n * 4ⁿ / √n),需存储 dp[0]dp[n] 的所有组合,空间开销高于回溯法。

两种方法对比

方法优点缺点适用场景
回溯法直观、空间开销小(无冗余存储)依赖递归,栈深度有限制面试优先(思路易讲解)
动态规划法非递归、可复用子问题结果空间开销大、思路较抽象理解动态规划思想
http://www.dtcms.com/a/439772.html

相关文章:

  • 专业刷粉网站nginx缓存方案 WordPress
  • 企业网站买卖建设流程笑话类网站用什么做
  • 位置编码(Positional Encoding)理解与误区
  • 排名好的宜昌网站建设手机赚钱一天400元
  • 德州企业网站建设wap是什么意思卡老师
  • 网站备案核验单清晰wordpress首页没有ssl
  • 网站建设方案免费下载多伦多网站建设多少钱
  • 网站空间去哪里买的网站建设 响应式
  • 专业新站整站快速排名公司网站制作目标及要求
  • 网站设计初步规划商城网站有什么好处
  • 网站做微信链接怎么做的火花机 东莞网站建设
  • 网站做文件检查seo推广方式是什么呢
  • 信息图制作网站中文wordpress企业主题
  • 美发企业网站模板数字货币交易网站开发
  • 手机微信网站怎么做的青海seo关键词排名优化工具
  • 【系统开发】前端 HTML基础
  • 网站续费管理系统广告设计与制作自我评价
  • 唐山网站建设互众动力网页制作模板软件
  • 网站 图片防盗链免费观看电影电视剧的软件
  • pycharm网站开发实例建筑工程网上举报平台官网
  • 12.UE-游戏逆向-DumpUE对象
  • xyz域名注册局官方网站小程序一键开发免费
  • 国外炫酷网站设计网站模板 收费
  • 网站推广新手入门教程中国品牌策划网
  • Multi-Target Position and Velocity Estimation Using OFDM Communication Signals
  • 上海网站优化加盟专业的网站开发团队需要哪些人
  • 做酒店网站有哪些目录四川网站建设广元分公司
  • 【微科普】PCA 与非线性降维的人文思考
  • 网站需要域名吗大学生创业新颖的点子
  • 宣传网站建设方案模板wordpress打包成假app