原题目
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
提示: 1 <= n <= 8
图解
解题思路
-
由题可知,输出的是一个数组,那么就可以联想到递归
-
数组中的元素是字符串,也就是说每次递归调用需要拼接字符串。
-
字符串拼接就是一个从左向右或者从右到左依次添加字符的过程,这个大家都知道。这里用的是从左向右添加字符的思路,每次拼接字符,都只要考虑接下来要拼接的是 “(” 还是 “)” 。
-
需要生成 有效的括号 ,那么字符串第一个位置的字符必定是 “(”。如果是 “)” ,那么后面不管拼接的是什么都是不成对的括号组合。
“)(”
“)())”
…
以此类推,验证了思路 4 的正确性
- 那么如何判断接下来拼接的是 “(” 还是 “)” 呢?
“(” 只要有就可以选,因为第一次必须要选 “(” ,关键在于 “)” 的选择。
“(()))(”
“()))((”
…
不知道你能不能理解我想表达的意思,就是破坏括号的成对性是 “)” 的拼接位置,而不在于 “(”
如果期望 “)” 不破坏括号的成对性,那么条件就是,剩余的 “)” 数量要大于 “(” 的剩余数量。
比如说有 3 对括号
首先显示 “()”, 此时左右括号各剩 2个
那么接下来第三个位置拼接的必须是 “(”,也就是 “()(”
如果你拼接的是 “)”,那么 “())”,这样的话,后面无论如何拼接,括号都不再成对了
当 “()(”,此时左括号省 1 个,右括号剩两个,那么接下来你想拼接 “(” 或者 “)” 都可以
选 “(” ,“()((”,那么最后结果就是 “()(())”
选 “)”, “()()”,那么最后结果就是 “()()()”
代码
var generateParenthesis = function (n) {
let res = []; // 输出的是数组,先定义一个空数组,记录结果
let dfs = (cur, left, right) => {
if (cur.length === 2 * n) {
res.push(cur);
return;
}
// 左括号还存在,就可以选左括号
if (left > 0) {
dfs(cur + "(", left - 1, right);
}
// 右括号数量要大于左括号,才可以选右括号
if (right > left) {
dfs(cur + ")", left, right - 1);
}
};
dfs("", n, n);
return res;
};
console.log(generateParenthesis(3));