leetcode top100挑战, 每天不鸽一道题之 括号生成(11/100)

157 阅读2分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

题目描述

括号生成

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

leetcode-cn.com/problems/ge…

// 示例1 
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
// 示例2 
输入:n = 1
输出:["()"]

标签

dfs递归

解题分析

1. 递归

直接上讲解。

这道题挺麻烦也应简单的。。直接用递归,根据传入的n,也就是生成括号对数,生成所有可能的括号排列组合。
用之前用过的dfs回溯递归可以解决,慢慢开始做题了之后我就发现这种需要返回所有可能的题目就回溯递归贼好用。

第一次进入递归函数,肯定需要生成第一个右括号(。
第二次进入递归函数,这时有两种可能,(和)两条路。
然后开始分叉,

                         1
                         (
          2                            3
          ()                           ((

 4                 5           6                  7
()(               ())         (()                (((

这里我们要判断下,如果右括号数量大于左括号,那就不符合题意了,第5个递归函数需要返回不跑了。

就这样每次递归,直到左右括号的数量等于传入的n,也就是生成的括号对数时,就把当前生成的括号字符串推入结果中保存。
所有递归函数结束了之后就得到了我们响应的结果。

来人上代码!!!!!

function generateParenthesis(n: number): string[] {
    const result:string [] = []
    const dfs = (path: string, count1: number, count2: number) => {
        // path为递归的字符串,count1为左括号的数量,count2为右括号的数量
        // 当左括号或右括号大于传入的n,括号生成后的岁数,那这个递归函数就不跑了。
        if(count1 > n || count2 > n) return
        // 如果右括号的数量大于左括号的数量,也不符合题意,也不跑了。
        if(count2 > count1) return 
        // 左括号和右括号的数量都对了 那就把正确结果推出去
        if(count1 === n && count2 === n) {
            result.push(path)
            return 
        }

        //这边处理第一次传入空字符串的情况
        if(count1 === 0) {
            dfs(path + '(', count1 + 1, count2)
        }
        else {
            // 只有这两种结果
            dfs(path + '(', count1 + 1, count2)
            dfs(path + ')', count1, count2 + 1)
        }
    }
    dfs('', 0, 0)
    return result
};

最后

从今天开始不鸽,每天一道算法题并发布文章,首先想要解决的题组为Top100,第十一道题目打完收工!!