目录
一、问题描述
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
二、解题思路
解题思路:
- 递归构造:在生成括号时,我们需要确保左括号
(
数量不超过n
,同时右括号)
的数量不能超过左括号的数量。 - 有效性判断:
- 只有在已添加的左括号数量小于
n
时,才可以添加左括号。 - 只有在右括号的数量小于左括号时,才可以添加右括号。
- 只有在已添加的左括号数量小于
- 回溯思想:通过递归来逐步生成每种可能的括号组合,当满足条件(即生成的括号数量达到
2 * n
且合法)时,将结果添加到结果集中。
三、代码
class Solution {
// 定义主函数,返回所有有效的括号组合
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>(); // 存储所有的结果
// 辅助回溯函数,从空字符串开始构造
backtrack(result, "", 0, 0, n);
return result;
}
// 回溯函数定义:result 保存结果,current 当前的构造字符串,open 已使用的左括号数量,close 已使用的右括号数量,n 是括号对数
private void backtrack(List<String> result, String current, int open, int close, int n) {
// 如果当前字符串的长度达到 2 * n,说明已经生成了一个完整的括号组合
if (current.length() == n * 2) {
result.add(current); // 将该组合加入结果集中
return;
}
// 如果左括号数量小于 n,继续添加左括号
if (open < n) {
backtrack(result, current + "(", open + 1, close, n);
}
// 如果右括号数量小于左括号数量,继续添加右括号
if (close < open) {
backtrack(result, current + ")", open, close + 1, n);
}
}
}
代码详解:
- 主函数
generateParenthesis
:- 创建一个
ArrayList<String>
来保存最终的结果。 - 调用递归的回溯函数
backtrack
来构造所有可能的有效括号组合。
- 创建一个
- 回溯函数
backtrack
:- 递归终止条件:当当前生成的字符串长度达到
2 * n
时,说明已经构造完成一个有效的括号组合,将其加入结果集中。 - 添加左括号:如果当前的左括号数量小于
n
,可以继续添加左括号。 - 添加右括号:右括号的数量必须小于左括号时才能添加,因为右括号必须在左括号之后匹配。
- 递归终止条件:当当前生成的字符串长度达到
四、复杂度分析
- 时间复杂度:
O(4^n / sqrt(n))
,该复杂度来源于卡特兰数,代表生成括号序列的总数目。 - 空间复杂度:
O(n)
,递归的深度是2 * n
,因此每次递归调用消耗的空间为O(n)
。