leetcode#22 括号生成

120 阅读1分钟

给你一个数字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,然后继续递归
    }

}