LeetCode100--22. 括号生成
题目
数字 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 个括号中的左括号个数 - 右括号个数 = balanceprivate 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+rightpath.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`函数是该类的成员之一,用于生成所有有效的括号组合
