每日一题--括号生成

146 阅读1分钟

这是我参与11月更文挑战的第25天,活动详情查看:[2021最后一次更文挑战]

题目

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

有效括号组合需满足:左括号必须以正确的顺序闭合。

示例 1:

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

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

1 <= n <= 8

思路

这一类问题是在一棵隐式的树上求解,可以用深度优先遍历,也可以用广度优先遍历。 一般用深度优先遍历。原因是:

代码好写,使用递归的方法,直接借助系统栈完成状态的转移; 广度优先遍历得自己编写结点类和借助队列。 这里的「状态」是指程序执行到 隐式树 的某个结点的语言描述,在程序中用不同的 变量 加以区分。

方法一:深度优先遍历 我们以 n = 2 为例,画树形结构图。方法是 「做减法」。

当前左右括号都有大于 00 个可以使用的时候,才产生分支; 产生左分支的时候,只看当前是否还有左括号可以使用; 产生右分支的时候,还受到左分支的限制,右边剩余可以使用的括号数量一定得在严格大于左边剩余的数量的时候,才可以产生分支; 在左边和右边剩余的括号数都等于 00 的时候结算。

代码

代码好写,使用递归的方法,直接借助系统栈完成状态的转移;
广度优先遍历得自己编写结点类和借助队列。
这里的「状态」是指程序执行到 隐式树 的某个结点的语言描述,在程序中用不同的 变量 加以区分。
var generateParenthesis = function (n) {
    let res = [];
    const help = (cur, left, right) => {
        if(cur.length === 2 * n) {
            res.push(cur);
            return;
        }
        if(left < n) {
            help(cur+ '(',left + 1, right)
        }
        if(right < left) {
            help(cur + ')', left, right + 1)
        }
        
    }
    
    help("", 0, 0)
    return res
};