题目
数字
n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
解答
图片来源于视频截图https://www.bilibili.com/video/BV1mPimYGE4q?p=54&vd_source=b42b3b4ccc197fbbaf3f1dbdb048417a
图中数字是左右括号剩余数量
算法思路
-
初始化:创建一个空数组
ans
来存储所有有效的括号组合。 -
深度优先搜索(DFS):
-
str
:当前构建的括号字符串 -
left
:剩余可用的左括号数量 -
right
:剩余可用的右括号数量
-
-
递归过程:
-
边界条件:当字符串长度达到 2n 时,说明得到一个有效组合,将其加入结果数组
-
添加左括号:只要还有剩余的左括号(
left > 0
),就可以添加左括号 -
添加右括号:只有当剩余的右括号比左括号多时(
right > left
)才能添加右括号(这保证了括号的有效性)
-
-
初始调用:从空字符串开始,初始可用的左右括号数均为 n。
示例解析(n=2)
递归调用过程:
-
初始调用
dfs('', 2, 2)
-
添加 '(' →
dfs('(', 1, 2)
-
添加 '(' →
dfs('((', 0, 2)
-
只能添加 ')' →
dfs('(()', 0, 1)
-
只能添加 ')' →
dfs('(())', 0, 0)
→ 加入结果
-
-
-
添加 ')' →
dfs('()', 1, 1)
-
添加 '(' →
dfs('()(', 0, 1)
-
添加 ')' →
dfs('()()', 0, 0)
→ 加入结果
-
-
不能直接添加 ')'(因为 right == left)
-
-
最终结果:['(())', '()()']
var generateParenthesis = function(n) {
// 存储所有有效括号组合的结果数组
let ans = [];
/**
* 深度优先搜索(DFS)递归函数
* @param {string} str - 当前构建的括号字符串
* @param {number} left - 剩余可用的左括号数量
* @param {number} right - 剩余可用的右括号数量
*/
let dfs = (str, left, right) => {
// 递归边界条件:当字符串长度达到2n时(即用完所有括号)
if (str.length === n * 2) {
ans.push(str); // 将完整组合加入结果数组
return;
}
// 只要还有左括号可用,就可以添加左括号
if (left > 0) {
// 添加左括号,剩余左括号数量减1
dfs(str + "(", left - 1, right);
}
// 只有当剩余的右括号比左括号多时,才能添加右括号
// 这保证了括号的有效性(不会出现无效的右括号)
if (right > left) {
// 添加右括号,剩余右括号数量减1
dfs(str + ")", left, right - 1);
}
};
// 从空字符串开始,初始可用的左右括号数均为n
dfs('', n, n);
// 返回所有有效的括号组合
return ans;
};