括号生成[中等][递归/深度优先遍历/动态规划]

234 阅读1分钟

题目

image.png

深度优先遍历

思路

  1. 定义left为剩余的左括号'('数量,right为剩余的右括号')'数量
  2. 对于一个合法的括号组成的字符串,有这样的一个规则:在该字符串的任意前缀的位置上,都有剩余的左括号数量小于等于剩余的右括号的数量,即left <= right。这样可以保证剩余的右括号将左括号包围住,实现闭合, 如果不满足的话,那么一定无法做到括号的闭合。
  3. 按照上面的规则, 从头开始构建字符串, 查看当前的left和right:
    • 如果left < right, 为了保证在下一个状态实现left<=right, 此时可以在后面加上'('或者是')',
    • 如果left == right, 为了保证在下一个状态实现left<=right, 当前只能在后面加上'('来实现left减小,实现下一个状态是left<right。如果加上')',就会导致right<left,所以在这种情况下不能加上')'。
  4. 当left === 0 且 right === 0的时候,表示没有了剩余的字符串,此时可以将当前获得的字符串加入到答案里面。

代码

/**
 * @param {number} n
 * @return {string[]}
 */
var generateParenthesis = function(n) {
    let answer = [];
    // 剩余的右括号数量应该大于等于左括号的数量
    let dfs = (str, left, right)=>{
        if(left < 0 || right < 0){
            return;
        }
        if(right === 0 && left === 0){
            answer.push(str);
            return;
        }
        if(left < right){
            dfs(str+"(", left - 1, right);
            dfs(str+")", left, right - 1);
        }else{
            dfs(str+"(", left - 1, right);
        }
    }
    dfs("", n, n);
    return answer;
};

动态规划

思路

求解n对括号的有效排列,相当于是求解 n-1对括号的有效排列 + ()的过程,所以 子问题 = n-1对括号的有效排列 同时对于括号的放置位置,可以将n-1对括号拆成两部分,即 a + b = n-1, a 取值从0~(n-1),括号的放置位置是(a) + b。

代码

/**
 * @param {number} n
 * @return {string[]}
 */
var generateParenthesis = function(n) {
    let temp = new Array(9);
    for(let i = 0; i < 9; i++){
        temp[i] = new Array();
    }
    let dp = (depth)=>{
        if(temp[depth].length > 0){
            return;
        }
        if(depth === 0){
            temp[depth].push("");
        }else if(depth == 1){
            temp[depth].push("()");
        }else{
            for(let a = 0; a < depth; a++){
                let b = depth - a - 1;
                dp(a);
                dp(b);
                for(let i = 0; i< temp[a].length; i++){
                    for(let j = 0; j< temp[b].length; j++){
                        let str = "("+temp[a][i]+")"+temp[b][j];
                        temp[depth].push(str);
                    }
                }
            }
        }
    }
    dp(n);
    return temp[n];
};