Leetcode 括号生成 js

1. 暴力解法

括号-暴力

  • 输入n个,就有n对括号,那么总共是2n个字符位置,
  • 2n个位置 每个字符都可以是 ( 或者 )一共有2的2n次方个不同的字符串
  • 判断所有的解法中有效的字符串即可
var generateParenthesis = function (n) {
    
    
    if (n < 1) return [
    let res = [];

    // 判断一个组合是否有效
    function valid(arr) {
    
    
      let b = 0, i = 0;
      for (; i < arr.length; i++) {
    
    
        if (arr[i] === '(') {
    
    
          b++;
        } else {
    
    
          b--;
        }
        // b < 0 代表前边多一个 ) 肯定没法闭合了
        if (b < 0) return false;
      }
      return b === 0;
    }

    function generateAll(cur, pos) {
    
    
      cur = [...cur]
      if (pos === cur.length) {
    
    
        if (valid(cur)) res.push(cur.join(""))
      } else {
    
    
        let c1 = [...cur]
        c1[pos] = '('
        generateAll(c1, pos + 1);

        let c11 = [...cur]
        c11[pos] = ')'
        generateAll(c11, pos + 1);
      }
    }

    generateAll(Array(n * 2), 0)
    return res;
  };
  console.log(generateParenthesis(3));

2. 暴力解法优化 回朔法 + 剪枝

其实不用每个都判断有没有效,结果可以缓存 ( 记做 left 的数量 和 )记做 right的数量
一旦right > left 直接return left大于n个也return,可以避免大量多余的运算 ,如果能提前分析出,走这一条路并不能得到想要的结果,可以跳过这个分支,这一步操作叫 剪枝

var generateParenthesis = function (n) {
    
    
    if (n < 1) return []
    let res = [];
    function generateAll(cur, pos) {
    
    
      if (cur.left > n || cur.right > cur.left) {
    
    
        return;
      }
      if (pos === cur.length) {
    
    
        res.push(cur)
      } else {
    
    
        let c1 = {
    
    ...cur};
        c1[pos] = '(';
        c1.left++;
        generateAll(c1, pos + 1);

        let c2 = {
    
    ...cur}
        c2[pos] = ')';
        c2.right++;
        generateAll(c2, pos + 1);
      }
    }
    generateAll({
    
    length: 2 * n, left : 0, right: 0}, 0);
    return res.map(e => Array.from(e).join(""))
  };

3. 动态规划 DP

这个就要明白 n+ 1 的解是 由n的解,( 和 a )b ,a和b位置放有效的结果形成的,并利用上一次的解
kuohao-dp

   function generateParenthesis (n) {
    
    
    let cache = [[""]];
    function fn(n) {
    
    
      if (cache[n]) return cache[n];
      let r = [];
      for (let a = 0; a < n; a++) {
    
    
        fn(a).forEach(left => {
    
    
          fn(n - a - 1).forEach(right => {
    
    
            r.push("(" + left + ')' + right)
          })
        })
      }
      cache[n] = r;
      return r;
    }
    return fn(n)
  }

猜你喜欢

转载自blog.csdn.net/qq_29334605/article/details/105661839