22. Generate Parentheses (Medium)
给你一个数字 n
,你需要用 n
对括号进行组合,找到所有可能的组合。
没对括号需要正常关闭才算一个有效的组合。
思路
把括号转换成数字,我们可以观察到其中的规律。转数字的方法在于对括号嵌套的层级进行计数,比如 ((()))
一共嵌套了 3 层,所以转化为数字为 123
,而 ()(())
可以转化为 112
。
Input: n = 3
Output: [“((()))”,”(()())”,”(())()”,”()(())”,”()()()”]
Layout: [123, 122, 121, 112, 111]
规律在答案中的所有组合都属于 1..n
到 1..1
的枚举。比如 123, 122, 121
的过程中最高位 3 被枚举到 1,而下一个数第二位 2 降为 1,第三位从第二位原本的值开始继续枚举到 1。
我们可以将其转化为算法,计算出所有可能的嵌套布局,然后用一个 draw
方法来将布局转化为实际的括号字符串。转化过程有三种模式:
- 对排列的最后一个元素的处理:插入一对括号,然后关闭其他所有括号;
- 对当前元素 >= 下一个元素的处理:插入一对括号,关闭到下一个元素为止层级的括号;
- 对当前元素 < 下一个元素对处理:插入左半边括号。
class Solution: |
上面的思路只是找到了题目的答案,但是算不上优雅。对字符串的编辑可以在计算布局的适合完成,或者说,一旦我们知道了布局的规律,我们就可以完全没有额外操作的找到所有组合。
但是在编辑字符串的适合很容易陷入到对多种情况的考虑,但是只要换一个角度想想问题就可以解决:括号会出现在哪里?
实际上合理的括号只会出现在两个位置:当前括号的里面(嵌套变深),当前括号的右边(非嵌套)。
下一个问题是,哪些括号放在里面,哪些放在右边呢?答案是,从 n
到 1
遍历,当前的 index
在括号里面,n - index
在括号的右边,当然反之亦然,影响的只是答案中每个元素出现的顺序而已。
class Solution: |
相关文章