22. Generate Parentheses
Leetcode 问题: 22. Generate Parentheses
		
		Categories:
题目
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
传入一个整数 n,产生出数量为 n 对 的括号组合阵列
Example
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Input: n = 1
Output: ["()"]
演算法
1. 设定括弧 Stack 储存资料
因为括弧是按照顺序才能够成为一个合法的括弧,所以用 Stack 的 push 及 pop 控制括弧资料为 先进后出 FILO 的方式
- 开启的括弧,必须有一个
结束的同类型括弧 - 开启的括弧,必须用
正确的顺序结束括弧关闭 
2. 当 起始括弧 ( 数量小于目标括弧对数,继续加入起始括弧
当起始括弧 (数量未达指定上限数量时,表示都还可以加入起始括弧 (
那就将起始括弧 (加入到 Stack 中
然后将起始括弧数量 +1,递迴呼叫括弧产生函数
产生结束后,Stack.pop() 移除刚刚加入的起始括弧 (
3. 当 结束括弧 ) 数量小于起始括弧 (数量,加入结束括弧
结束括弧 ) 数量不可以比  起始括弧 ( 数量还多,这样会变成不合法的括弧字串
当要加入 结束括弧 ) 前,在前方必须有足够数量的 起始括弧 ( 才能够加入
()): 不合法
所以当「结束括弧数量」小于「起始括弧数量」,表示可以加入结束括弧
然后将结束括弧数量 +1,递迴呼叫括弧产生函数
产生结束后,Stack.pop() 移除刚刚加入的 结束括弧 )
4. 产生合法的括弧
当 起始括弧 ( 、 结束括弧 ) 与 目标括弧对数 这三者的数量相同
表示已经将括弧顺序排列组合都排列出来了,将括弧 Stack 中的括弧字串 join 起来,储存到候选的括弧阵列
答案
JavaScript
function generateParenthesis(nPairParenthesis) {
    // 括号 Stack
    var parenthesisStack = [];
    // 最后的可能括号
    var finalPairParenthesisList = [];
    var backTrack = function (openParenthesisCount, closeParenthesisCount) {
        if (openParenthesisCount == nPairParenthesis && closeParenthesisCount == nPairParenthesis) {
            // 如果已经到最后的数量了
            // 将所有的括号 Stack join 起来
            var finalPairParenthesis = parenthesisStack.join('');
            finalPairParenthesisList.push(finalPairParenthesis);
            return;
        }
        if (openParenthesisCount < nPairParenthesis) {
            // 如果「起始括号数量」小于「目标括号成对数量」
            // 加入起始括号
            parenthesisStack.push("(");
            // 取得下一个括号资料
            backTrack(openParenthesisCount + 1, closeParenthesisCount);
            // 处理结束,将 Stack 中的括弧移除
            parenthesisStack.pop();
        }
        if (closeParenthesisCount < openParenthesisCount) {
            // 如果「结束括弧数量」小于「起始括弧数量」,表示可以加入结束括弧
            parenthesisStack.push(")");
            // 取得下一个括号资料
            backTrack(openParenthesisCount, closeParenthesisCount + 1);
            // 处理结束,将 Stack 中的括弧移除
            parenthesisStack.pop();
        }
    };
    // 从头开始计算括弧
    backTrack(0, 0);
    return finalPairParenthesisList;
}
TypeScript
function generateParenthesis(nPairParenthesis: number): string[] {
    // 括号 Stack
    let parenthesisStack: any = [];
    // 最后的可能括号
    let finalPairParenthesisList:string[] = [];
    let backTrack = (openParenthesisCount: number, closeParenthesisCount: number):void => {
        if (openParenthesisCount == nPairParenthesis && closeParenthesisCount == nPairParenthesis) {
            // 如果已经到最后的数量了
            // 将所有的括号 Stack join 起来
            let finalPairParenthesis = parenthesisStack.join('');
            finalPairParenthesisList.push(finalPairParenthesis);
            return;
        }
        if (openParenthesisCount < nPairParenthesis) {
            // 如果「起始括号数量」小于「目标括号成对数量」
            // 加入起始括号
            parenthesisStack.push("(");
            // 取得下一个括号资料
            backTrack(openParenthesisCount + 1, closeParenthesisCount);
            // 处理结束,将 Stack 中的括弧移除
            parenthesisStack.pop();
        }
        if (closeParenthesisCount < openParenthesisCount) {
            // 如果「结束括弧数量」小于「起始括弧数量」,表示可以加入结束括弧
            parenthesisStack.push(")");
            // 取得下一个括号资料
            backTrack(openParenthesisCount, closeParenthesisCount + 1);
            // 处理结束,将 Stack 中的括弧移除
            parenthesisStack.pop();
        }
    }
    // 从头开始计算括弧
    backTrack(0,0);
    return finalPairParenthesisList;
};