Offer 驾到,掘友接招!我正在参与 2022 春招打卡活动,点击查看活动详情。
一、题目描述:
- 括号生成-难度中等
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
提示:
1 <= n <= 8
二、题目和思路分析:
最开始我是这么想的:
括号是相同的
n对不同的括号的组合,就是左侧n个左右括号的不同排列组合,只要判断左侧括号的情况即可。
可当我准备写代码的时候才发现:
只判断左侧括号情况是不对的,想想上次的括号题目,有效的判断条件应该是【每个右括号都有一个与之对应的左括号】,那么可以先列出所有的可能性,再根据这个规则筛选。
可是这么想还是有些麻烦,如果列出可能性的时候,就进行判断,逻辑不就更简单些吗?
正当我准备顺着这个思路写代码,我又想到:
判断【每个右括号都有一个与之对应的左括号】这个逻辑写出来也是有点复杂的,那么有没有什么规律可以看看呢?
于是我把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
}
};
四、总结:
这道题看着简单,刚做的时候也以为很简单,主要是括号新增的规律不太好找,按目前这种遍历的方法耗时和内存都不乐观,不过实在想不到更高级的方法了。
加油吧!