LeetCode 22. 括号生成 回溯写法详解

22. 括号生成

题目来源

22. 括号生成

题目分析

给定一个数字 n,表示生成括号的对数,要求设计一个函数生成所有可能的并且有效的括号组合。

题目难度

  • 难度:中等

题目标签

  • 标签:数组, 回溯

题目限制

  • 1 <= n <= 8

解题思路

生成有效的括号组合,可以使用回溯算法。对于每个位置,我们可以选择放左括号或右括号。为了生成有效的组合,需要保证在任何位置,右括号的数量不能超过左括号的数量。
其实可以看成是2*n个位置,每个位置有两种选择,选择左括号,和不选择左括号即选右括号,这两种情况都向下递归就好了,只不过还要注意要用有效括号组合的约束条件剪枝。

核心算法步骤

  • 回溯算法
    1. 使用一个 StringBuilder 来记录当前路径(已经生成的括号串)。
    2. 遍历 2n 个位置:
      • 如果左括号数量还没有达到 n,则可以放一个左括号。
      • 如果右括号数量少于左括号数量,则可以放一个右括号。
    3. 当路径长度等于 2n 时,生成一个有效的括号组合,将其加入到结果集中。

代码实现

以下是生成符合条件的括号组合的 Java 代码:

/**
 * 22. 括号生成
 * @param n 输入的整数n
 * @return ans 所有可能的组合
 */
public List<String> generateParenthesis(int n) {
    List<String> ans = new ArrayList<>();
    StringBuilder path = new StringBuilder();
    generateParenthesis(n, 0, path, ans);
    return ans;
}

private void generateParenthesis(int n, int i, StringBuilder path, List<String> ans) {
    if (path.length() == 2 * n) {
        ans.add(path.toString());
        return;
    }
    // 选择 左括号 i为左括号个数
    if (i < n) {
        path.append("(");
        generateParenthesis(n, i + 1, path, ans);
        path.deleteCharAt(path.length() - 1);
    }
    // 选择 右括号
    if (path.length() - i < i) {
        path.append(")");
        generateParenthesis(n, i, path, ans);
        path.deleteCharAt(path.length() - 1);
    }
}

代码解读

  • 回溯逻辑

    • generateParenthesis 方法用于生成所有有效的括号组合。通过递归的方式,分别在每个位置选择添加左括号或右括号。
    • i 表示当前已经添加的左括号的数量。左括号的数量不能超过 n,且右括号的数量不能超过当前的左括号数量。
  • 路径管理

    • 使用 StringBuilder 管理当前生成的路径,生成一个有效的组合后,使用 ans.add(path.toString()) 将其加入结果集中。
    • 在递归回溯时,使用 deleteCharAt 方法撤销最后一次操作,以恢复到上一步的状态。

性能分析

  • 时间复杂度O(2^n),由于回溯算法会尝试生成所有可能的括号组合(无效组合会被剪枝)。
  • 空间复杂度O(n),递归调用栈的最大深度为 2*n

测试用例

你可以使用以下测试用例来验证代码的正确性:

int n = 3;
List<String> result = generateParenthesis(n);
System.out.println(result);
// 输出: ["((()))", "(()())", "(())()", "()(())", "()()()"]

int n2 = 1;
List<String> result2 = generateParenthesis(n2);
System.out.println(result2);
// 输出: ["()"]

扩展讨论

优化写法

在回溯过程中,可以根据剩余左右括号的数量提前判断是否可能生成有效的组合,以减少无效组合的生成,提升效率。

其他实现

除了回溯法,动态规划也可以用来解决括号生成问题。通过构造递归方程,可以从较小的子问题逐步构造出最终的解。

总结

这道题目通过回溯算法帮助我们理解了如何生成所有有效的括号组合。该算法的核心是递归地选择放置左括号或右括号,并通过路径管理和剪枝优化来提高效率。这种思路可以有效地解决类似的组合生成问题。


  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值