前端算法(22)

91 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

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

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

题目解析

思路一

我们这里使用递归函数进行实现,每轮循环可以放左括号,也可以放右括号

var generateParenthesis = function(n) {
  const arr = []
   // left: 当前左括号的数量,right: 当前右括号的数量, s当前的字符串
  const generate = (left, right, s) => {
    if (left == n && right == n) {
      arr.push(s)
      return
    }
    // 可以添加一个左括号,也可以添加一个右括号
    // 此时要只生成合法的括号, 左括号<n,可以继续添加左括号;右括号<左括号<=3,可以继续添加右括号
    if (left < n) {
      generate(left + 1, right, s + '(')
    }
    if (right < left) {
      generate(left, right + 1, s + ')')
    }
  }
  generate(0, 0, '')
  return arr
};

思路二

这里我们也是使用的递归,不过是递归的另一种思路

var generateParenthesis = function(n) {
    let arr = []; //存储最后输出的有效的括号组合
    let string = ''; //初始化的括号字符串
    let open = 0; //当前字符串,左括号的个数
    let close = 0; //当前字符串,右括号的个数
    function back(arr, string, open, close, max) {
        if(string.length === max * 2){ //如果此字符串的长度等于括号的对数乘2,就说明符合条件,存进结果数组
            arr.push(string);
            return;
        }
        if(open < max){ //当左括号的数量小于给定的括号对数,那么就为它在后面再添加一个新的'('
            string += '(';
            back(arr, string, open + 1, close, max); //递归,回溯(将左括号的数量+1,传进下一次函数中)
            string = string.substring(0, string.length - 1); //截取掉新添加的‘(’,再用这个字符串执行‘右括号’的判断(substring,截取时含头不含尾)
        }
        if(close < open){ //当右括号的数量小于左括号的数量(括号不是一一对应的关系),那么就执行下面的操作
            string += ')'; //为字符串新添加一个‘)’
            back(arr, string, open, close + 1, max); //(将右括号的数量+1,传进下一次递归函数中)
            string = string.substring(0, string.length - 1); //截取掉当前字符串的最后一位字符(‘)’)
        }
    }
    back(arr, string, open, close, n); //调用 back 函数,传入指定的参数
    return arr; //把最后的结果数组输出
};