【算法】括号生成

155 阅读2分钟

难度:中等

题目:

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 8

解题思路:

这个问题可以通过回溯算法(Backtracking)来解决。回溯算法是一种通过尝试搜索所有可能的候选解来寻找问题解的算法,当发现当前路径无法达到解时,就“回溯”并尝试其他路径。

对于括号生成问题,我们可以遵循以下规则:

  1. 在任何时刻,左括号的数量都不能少于右括号的数量;
  2. 只有在左括号数量大于右括号数量时,才能添加右括号;
  3. 当左右括号的数量都达到n时,我们就找到了一组有效的括号组合。

基于上述规则,我们可以设计如下算法:

  1. 初始化一个空字符串作为当前的括号组合;
  2. 使用递归函数,传入当前的括号组合,以及剩余可以添加的左括号和右括号的数量;
  3. 在递归函数中,如果剩余的左括号数量大于0,那么我们可以添加一个左括号,并递归调用自身,减少一个左括号的数量;
  4. 如果剩余的右括号数量大于当前左括号的数量,那么我们可以添加一个右括号,并递归调用自身,减少一个右括号的数量;
  5. 当左括号和右括号的数量都为0时,我们找到了一组有效的括号组合,将其加入到结果列表中;
  6. 最后返回结果列表。

JavaScript实现:

/**
 * @param {number} n
 * @return {string[]}
 */
var generateParenthesis = function(n) {
    const result = [];

    function backtrack(s = '', left = 0, right = 0) {
        if (s.length === n * 2) {
            result.push(s);
            return;
        }
        if (left < n) {
            backtrack(s + '(', left + 1, right);
        }
        if (right < left) {
            backtrack(s + ')', left, right + 1);
        }
    }

    backtrack();
    return result;
};