1. 问题理解与解法概述
括号生成问题是LeetCode上经典的递归与回溯算法练习题。给定数字n,我们需要生成所有由n对括号组成的有效组合。有效括号组合必须满足:每个左括号都能找到对应的右括号闭合,并且在任何位置右括号的数量都不能超过左括号。
这个问题看似简单,但蕴含着递归思想的精髓。我在第一次接触这个问题时,花了整整一个下午才真正理解其中的递归逻辑。通过反复调试和画图分析,最终掌握了这个算法的核心要点。
1.1 问题本质分析
括号生成问题的本质是生成所有满足特定条件的排列组合。关键在于理解什么是"有效的"括号组合:
- 在任何前缀中,左括号的数量必须≥右括号数量
- 最终左括号和右括号的总数必须相等(各为n个)
这就像是在玩一个填格子游戏:每一步你都有两种选择(放左括号或右括号),但要遵守上述两条规则。违反任何一条规则,当前的组合就是无效的。
1.2 解法思路选择
解决这个问题主要有三种思路:
-
暴力枚举+验证:生成所有可能的2^(2n)种组合,然后逐个验证有效性。这种方法时间复杂度高达O(2^(2n)*n),效率极低。
-
递归回溯:在生成过程中就保证有效性,通过剪枝避免无效路径。这是最优雅的解法,时间复杂度约为O(4^n/√n),即卡特兰数的增长速度。
-
动态规划:基于较小n的解构造较大n的解。虽然可行,但实现起来不如递归直观。
本文重点讲解第二种方法——递归回溯,因为它最能体现算法设计的精髓,也是面试中最常考察的解法。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 递归回溯算法详解
递归回溯是解决括号生成问题的核心方法。让我们深入分析这个算法的每个细节。
2.1 递归函数设计
递归函数需要跟踪以下状态:
- 剩余可用的左括号数量(left_num)
- 剩余可用的右括号数量(right_num)
- 当前构建的字符串(s)
- 结果集合(ans)
递归终止条件是左右括号都用完(left_num == 0 && right_num == 0),此时将当前字符串加入结果集。
2.2 递归选择与剪枝
在每一步递归中,我们有两种选择:
- 添加左括号:只要还有剩余的左括号(left_num > 0)就可以选择
- 添加右括号:只有在已添加的左括号比右括号多时(rig
