LeetCode22:括号生成

原题地址:. - 力扣(LeetCode)

题目描述

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

示例 1:

复制代码
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

复制代码
输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

实现思路

题目要求生成所有有效的括号组合。有效的括号组合是指每个左括号 ( 都有对应的右括号 ),且在任意前缀中左括号的数量不少于右括号的数量。

思路:

  1. 回溯法 :使用回溯法生成所有可能的括号组合。可以用一个字符数组 current 来存储当前的组合。
  2. 递归生成:在每个位置上可以选择放入左括号或右括号。
  3. 验证有效性:在生成完整的组合后,通过一个辅助函数检查该组合是否有效。
  4. 结束条件:当字符数组填满时,检查组合的有效性,并将有效的组合添加到结果列表中。

源码实现

java 复制代码
class Solution {
    public List<String> generateParenthesis(int n) {
        // 创建一个列表来存储所有有效的括号组合
        List<String> combinations = new ArrayList<String>();
        // 调用递归函数生成所有可能的组合
        generateAll(new char[2 * n], 0, combinations);
        return combinations;
    }

    public void generateAll(char[] current, int pos, List<String> result) {
        // 如果当前位置到达数组末尾
        if (pos == current.length) {
            // 检查当前组合是否有效
            if (valid(current)) {
                // 如果有效,添加到结果列表
                result.add(new String(current));
            }
        } else {
            // 在当前位置放入左括号
            current[pos] = '(';
            generateAll(current, pos + 1, result); // 递归生成下一位置的组合
            
            // 在当前位置放入右括号
            current[pos] = ')';
            generateAll(current, pos + 1, result); // 递归生成下一位置的组合
        }
    }

    public boolean valid(char[] current) {
        int balance = 0; // 用于跟踪括号的平衡情况
        for (char c : current) {
            if (c == '(') {
                ++balance; // 左括号增加平衡
            } else {
                --balance; // 右括号减少平衡
            }
            // 如果平衡小于零,说明右括号多于左括号,组合无效
            if (balance < 0) {
                return false;
            }
        }
        // 只有当平衡为零时,才说明所有括号有效
        return balance == 0;
    }
}

复杂度评估

  • 时间复杂度:

    • 最坏情况下,算法会生成 O(2^(2n)) 种组合,这是由于每个位置都有两种选择(( 或 )),且组合的长度为 2n。
    • 然而,实际上有效的组合数量是 Catalan 数 C(n) = (2n)! / ((n+1)! * n!),因此实际生成的组合数会远少于 O(2^(2n))。
  • 空间复杂度:

    • 使用的空间主要是 result 列表和 current 数组。current 数组的长度为 2n,而 result 列表存储所有有效组合,最多为 O(C(n))。
    • 总体空间复杂度为 O(n)(用于存储 current 数组)加上 O(C(n))(存储有效组合),所以可以认为是 O(C(n))
相关推荐
xxwl585几秒前
第六章---计算几何
笔记·学习·算法
她的男孩6 分钟前
Spring Boot 4 升级别只看编译绿:Forge Admin 在 Jackson、Tomcat JSON 限流、MP 包名与 Flowable 库上踩过的坑
java·spring boot·后端
Knight_AL7 分钟前
别把 ThreadLocal 写进 Jackson Serializer
java·spring boot·spring
Song_RsHt18 分钟前
Gateway (上):路由与转发,微服务的统一入口
java·笔记·后端·学习·gateway
paopaokaka_luck29 分钟前
校园新闻推荐系统(DeepSeek新闻助手、个性化推荐算法、 Redis热词排行榜、ECharts运营分析、互动与实时通知、新闻运营闭环)
java·spring boot·mysql·spring·tomcat·echarts·intellij idea
yuniko-n34 分钟前
【JUC】线程池
java·开发语言
小天源40 分钟前
智叟云集政策监测技术方案——原文解析、证据提取与可核验摘要
java·服务器·数据库
yuzhiboyouye1 小时前
我现在得后端状况以及需要做的
java
小羊没烦恼!1 小时前
在.net中读写config文件的各种方法
java·大数据·运维·服务器·前端·数据库·oracle
Logic1011 小时前
C语言/数据结构二维数组题解:找出行列O个数均为偶数的格子——奇偶性预处理+二次遍历
c语言·数据结构·算法·二维数组·时间复杂度·动态内存分配·奇偶性