【力扣刷题记 22】——《括号生成》

206 阅读2分钟

Offer 驾到,掘友接招!我正在参与 2022 春招打卡活动,点击查看活动详情

一、题目描述:

  1. 括号生成-难度中等

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

示例 1:

输入:n = 3

输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1

输出:["()"]  

提示:

1 <= n <= 8

二、题目和思路分析:

最开始我是这么想的:

括号是相同的

n对不同的括号的组合,就是左侧n个左右括号的不同排列组合,只要判断左侧括号的情况即可。

可当我准备写代码的时候才发现:

只判断左侧括号情况是不对的,想想上次的括号题目,有效的判断条件应该是【每个右括号都有一个与之对应的左括号】,那么可以先列出所有的可能性,再根据这个规则筛选。

可是这么想还是有些麻烦,如果列出可能性的时候,就进行判断,逻辑不就更简单些吗?

正当我准备顺着这个思路写代码,我又想到:

判断【每个右括号都有一个与之对应的左括号】这个逻辑写出来也是有点复杂的,那么有没有什么规律可以看看呢?

于是我把1,2,3的情况列了一下

()

()() (())

()()() (()()) ()(()) (())() ((()))

大致列一下,可以发现,下一项是以上一项为基础,添加了一对括号。 添加的这对括号,有三种情况:

  1. 添加的这对括号包括上一个数组的每一项
  2. 添加的这对括号拼接上一个数组的每一项的左侧
  3. 添加的这对括号拼接上一个数组的每一项的右侧,但是上个数组的第一项()()...不再拼接,因为左侧或右侧拼接没有区别

逻辑没问题,那么代码写了出来。可是当我提交才知道,逻辑是有问题的:新增的括号可能在中间某个位置,而不是两边。

兜兜转转一大圈,我还是遍历添加吧!

又是一番修修改改,完工!

三、代码:

代码实现如下:

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

    return brackets(n)

    function brackets(n){
        if(n == 1){
            return ['()']
        }
        let arrN = brackets(--n)
        let arr = []
        for(let i = 0; i < arrN.length; i++){
            for(let j = 0; j < arrN[i].length; j++){
                let item = arrN[i].slice(0, j) + '()' + arrN[i].slice(j)
                if(!arr.includes(item)){
                    arr.push(item)
                }
            }
        }
        return arr
    }
};

四、总结:

这道题看着简单,刚做的时候也以为很简单,主要是括号新增的规律不太好找,按目前这种遍历的方法耗时和内存都不乐观,不过实在想不到更高级的方法了。

加油吧!

image.png