1. 题目
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
1 2
| 输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
|
示例 2:
提示:
2. 思路
- 初始化字符串结果集合
result
变量,同时采用回溯算法,如下:
1 2 3 4 5 6 7 8 9 10 11 12
| void backtracking(参数) { if (终止条件) { 存放结果; return; }
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) { 处理节点; backtracking(路径,选择列表); 回溯,撤销处理结果 } }
|
其中回溯函数中,参数分别是字符串、左括号计数变量left
与右括号计数变量right
,当左括号计数变量或右括号计数变量大于目标括号数量时,将直接终止回溯(此时回溯已经没有意义了,因为无法构成期望字符串)
当左右括号计数变量与目标括号数量一致时,说明已生成最终字符串,将其写入结果集合后终止回溯
如果均不满足以上条件,且当left
变量大于等于right
变量(说明左边是有富余的左括号,可以进行后续回溯操作)
- 先追加左括号,并进行下一层回溯,回溯完成后,移除刚刚加入的左括号
- 随后追加右括号,并进行下一层回溯,回溯完成后,移除刚刚加入的右括号
- (这一层回溯中,需要同步更新
left
变量和right
变量)
3. 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { private int target; private List<String> result = new ArrayList<>();
public List<String> generateParenthesis(int n) { this.target = n; var str = new StringBuilder(); helper(str, 0, 0); return result; }
private void helper(StringBuilder str, int left, int right) { if (left > target || right > target) { return; }
if (left - right == 0 && left == target) { result.add(str.toString()); return; }
if (left >= right) { str.append('('); helper(str, left + 1, right); str.deleteCharAt(str.length() - 1);
str.append(')'); helper(str, left, right + 1); str.deleteCharAt(str.length() - 1); } } }
|
4. 复杂度
- 时间复杂度:未知
- 空间复杂度:
O(n)
,空间主要消耗在递归层数
Author:
zchengb
License:
Copyright (c) 2019-2024 zchengb