本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
输入: n = 3
输出: ["((()))","(()())","(())()","()(())","()()()"]
题目解析
思路一
我们这里使用递归函数进行实现,每轮循环可以放左括号,也可以放右括号
var generateParenthesis = function(n) {
const arr = []
// left: 当前左括号的数量,right: 当前右括号的数量, s当前的字符串
const generate = (left, right, s) => {
if (left == n && right == n) {
arr.push(s)
return
}
// 可以添加一个左括号,也可以添加一个右括号
// 此时要只生成合法的括号, 左括号<n,可以继续添加左括号;右括号<左括号<=3,可以继续添加右括号
if (left < n) {
generate(left + 1, right, s + '(')
}
if (right < left) {
generate(left, right + 1, s + ')')
}
}
generate(0, 0, '')
return arr
};
思路二
这里我们也是使用的递归,不过是递归的另一种思路
var generateParenthesis = function(n) {
let arr = []; //存储最后输出的有效的括号组合
let string = ''; //初始化的括号字符串
let open = 0; //当前字符串,左括号的个数
let close = 0; //当前字符串,右括号的个数
function back(arr, string, open, close, max) {
if(string.length === max * 2){ //如果此字符串的长度等于括号的对数乘2,就说明符合条件,存进结果数组
arr.push(string);
return;
}
if(open < max){ //当左括号的数量小于给定的括号对数,那么就为它在后面再添加一个新的'('
string += '(';
back(arr, string, open + 1, close, max); //递归,回溯(将左括号的数量+1,传进下一次函数中)
string = string.substring(0, string.length - 1); //截取掉新添加的‘(’,再用这个字符串执行‘右括号’的判断(substring,截取时含头不含尾)
}
if(close < open){ //当右括号的数量小于左括号的数量(括号不是一一对应的关系),那么就执行下面的操作
string += ')'; //为字符串新添加一个‘)’
back(arr, string, open, close + 1, max); //(将右括号的数量+1,传进下一次递归函数中)
string = string.substring(0, string.length - 1); //截取掉当前字符串的最后一位字符(‘)’)
}
}
back(arr, string, open, close, n); //调用 back 函数,传入指定的参数
return arr; //把最后的结果数组输出
};