题目
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]
示例 2:
输入:n = 1
输出:[“()”]
题解
class Solution {
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
dfs(0, 0, n, path, ans);
return ans;
}
// 目前填了 i 个括号
// 这 i 个括号中的左括号个数 - 右括号个数 = balance
private void dfs(int i, int balance, int n, List<Integer> path, List<String> ans) {
if (path.size() == n) {
char[] s = new char[n * 2];
Arrays.fill(s, ')');
for (int j : path) {
s[j] = '(';
}
ans.add(new String(s));
return;
}
// 枚举填 right=0,1,2,...,balance 个右括号
for (int right = 0; right <= balance; right++) {
// 先填 right 个右括号,然后填 1 个左括号,记录左括号的下标 i+right
path.add(i + right);
dfs(i + right + 1, balance - right + 1, n, path, ans);
path.removeLast(); // path.remove(path.size() - 1);
}
}
}
解析
出自:两种基本回溯思想:选或不选 / 枚举选哪个(Python/Java/C++/Go/JS/Rust)
class Solution {
//函数生成所有有效的括号序列,用于n对括号。我们将这个函数放入类中以便于访问`dfs`函数。
public List<String> generateParenthesis(int n) {
//初始化一个空的答案列表来存储有效括号的所有可能组合。
List<String> ans = new ArrayList<>();
//path是一个整型数组,用于记录当前状态(即哪个位置可以放入'('或')')。它初始时为空,但之后会随着递归调用的深入而变化。
List<Integer> path = new ArrayList<>();
//从0开始回溯查找有效括号的组合;当前左括号和右括号没有(balance=0),n对括号,路径数组,答案列表。我们调用我们的主函数"dfs"来填充ans列表以返回所有有效的组合结果。
dfs(0, 0, n, path, ans);
//最后,我们返回答案列表(所有的括号序列)作为输出。
return ans;
}
//深度优先搜索函数:用于递归填充path和ans列表的每个'('或')'位置。
private void dfs(int i, int balance, int n, List<Integer> path, List<String> ans) {
if (i * 2 == n ) { //如果我们已经放了2*括号数量的字符(左+右括号),
char[] s = new char[n * 2];//初始化一个新的char数组s。它的长度是2的n倍。所有元素最初都填充为')'。
Arrays.fill(s, ')'); //将s中的所有元素修改为')',用于平衡字符串。
for (int j : path) {//现在遍历path数组并对于每个位置'j'放一个'('。
s[j] = '(';
}
ans.add(new String(s)); //然后将填充了括号的字符串添加到答案列表中。
return;//结束dfs函数并返回前一个层次。
}
//这个循环生成所有的右括号情况(0-balance个)并进行递归搜索相应的情况;它保持平衡,以确保只在最后出现'('之前不出现')'。
for (int right = 0; right <= balance ; right++ ) {
//首先将right个')'添加到path数组中最前面。然后执行下一对递归调用:i+1和balance-right,表示放置了一个'('或')'并相应地调整了平衡因子。
path.add(0, i + right);
dfs(i + right + 1, balance - right + 1 , n , path, ans );
//在返回到上一个层次之前,从path数组中移除'当前添加的括号(右括号)'。这样做是为了保持平衡并为下一次对递归调用做好准备。
path.remove(0);
}
}
}; //结束类Solution块。`generateParenthesis`函数是该类的成员之一,用于生成所有有效的括号组合

654

被折叠的 条评论
为什么被折叠?



