给你一个数字n,要求生成n对括号,可以有多少种可能? 最容易想到的就是生成所有可能性,并检查每种可能的合法性。这是暴力算法,可行但不够优雅。能不能让每次生成的结构,都是合法的呢?可以采用回溯法:
function generateParenthesis(n: number): string[] {
let ans:string[] = [] //声明数组用于保存符合条件的结果
helper(ans,'',0,0,n)// 开始递归,传递初始值
return ans
};
/**
ans:存放符合条件的字符串
current:用于拼接括号的字符串,
left和right:分别用于目前使用的左右括号数量
n :要生成的括号对数
*/
function helper(ans:string[],current:string,left:number,right:number,n:number):void {
if(left === n && right === n) { //当左右括号数量一致时,current一定符合要求,因为在递归之前都有条件限定:left < n 或 right < left
ans.push(current) //保存符合条件的字符串
return
}
if(left < n) { // 左括号还没用完
current += '(' //那就再用一个
helper(ans,current,left + 1,right,n) //左括号数使用量+1,继续递归
current = current.slice(0,current.length - 1) //还可能放右括号,故删掉前面添加的左括号
}
if(right < left) {//放右括号的前提是右括号的使用数量小于左括号 ,这里为什么不需要right < n呢?实际上只要right < left,right就一定小于n
current += ')'
helper(ans,current,left,right + 1,n) //右括号使用数量+1,然后继续递归
}
}