Leetcode前端必会系列:括号生成

67 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 8

分析

根据题目的分析,我们如何根据参数生成所有的括号序列?此处很容易想到回溯的设计思想,根据此我们可以归纳出如下步骤

  1. 设计括号生成的回溯递归函数
  2. 递归函数的出口就是右边括号数量大于左边或者左边或者右边的数量超出了限制,直接退出
  3. 递归的累加一个左边括号
  4. 递归的累加一个右边括号
  5. 如果左边数量等于右边的数量,同时满足参数要求,返回结果
  6. 返回最后保存的数组

解答

 /**

 * @param {number} n

 * @return {string[]}

 */

var generateParenthesis = function(n) {

  let res = []

   const main = (left,right,str) =>{

    if(right>left || left>n || right>n) return

    if(left===right && left===n) {

      res.push(str)

    }

    main(left+1,right,str+'(')

    main(left,right+1,str+')')

   }

   main(0,0,"")

   console.log(res)

   return res

};

generateParenthesis(2)

通过题目的分析,我们通过回溯的设计过程完成了括号生成,值得注意的是我们需要让回溯的过程参数是形参,如果是对象传递导致参数无法回溯。这是十分重要的点。

总结

回溯的设计是十分基础且经典的算法,我们有必要牢固的掌握其设计本质和原理。