前端算法第一五五弹-括号生成

75 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

BFS

  • n=1时,组合情况仅一种:["()"]

  • n=2时

    • 遍历 n=1 的组合情况 ["()"]
    • 对于情况 "()",在该字符串每个位置填入一对括号 () 后得到:["()()","(())","()()"]
    • 去重得到最终组合情况为:["()()","(())"]
  • n=3时

    • 遍历 n=2 的组合情况 ["()()","(())"]
    • 对于情况 "()()",在每个位置填入一对括号 () 后得到:["()()()","(())()","()()()","()(())","()()()"]
    • 对于情况 "(())",在每个位置填入一对括号 () 后得到:["()(())","(()())","((()))","(()())","(())()"]
    • 去重得到最终组合情况为:["()()()","(())()","()(())","(()())","((()))"]
var generateParenthesis = function (n) {
    let set = new Set(['()']);
    for (let c = 2; c <= n; c++) {
        let nextSet = new Set();
        for (const s of set) {
            for (let j = 0; j <= s.length; j++) {
                nextSet.add(s.slice(0, j) + '()' + s.slice(j));
            }
        }
        set = nextSet;
    }
    return [...set];
};

递归

1.大致思路就是不停选括号,要么选左括号,要么选右括号,所以可以用dfs来实现 2.利用约束做剪枝,这里有两个约束条件

  • 只要左括号有剩,就可以选它,然后继续做选择(递归)
  • 右括号比左括号剩的多,才能选右括号,然后继续做选择(递归)
  • 当str的长度为 2 * n 时,结束递归
var generateParenthesis = function (n) {
  const res = [];

  const dfs = (lRemain, rRemain, str) => { // 左右括号所剩的数量,str是当前字符串
    if (str.length == 2 * n) { // 字符串构建完成
      res.push(str);           // 加入解集
      return;                  // 结束当前递归分支
    }
    if (lRemain > 0) {         // 只要左括号有剩,就可以选它,然后继续做选择(递归)
      dfs(lRemain - 1, rRemain, str + "(");
    }
    if (lRemain < rRemain) {   // 右括号比左括号剩的多,才能选右括号
      dfs(lRemain, rRemain - 1, str + ")"); // 然后继续做选择(递归)
    }
  };

  dfs(n, n, ""); // 递归的入口,剩余数量都是n,初始字符串是空串
  return res;
};

图片.png

/**
 * @param {number} n
 * @return {string[]}
 */
var generateParenthesis = function (n) {
    const res = []
    function dfs(l, r, s) {
        if (l === 0 && r === 0) {
            res.push(s)
            return
        }
        if (l > r) return
        if (l > 0) dfs(l - 1, r, s + '(')
        if (r > 0) dfs(l, r - 1, s + ')')
    }
    dfs(n, n, '')
    return res
};

图片.png