题意:
给定n对括号,返回括号的所有组合方式。
分析:
我们现在要遍历所有的组合选出满足条件的,实质是对一组数据的遍历。那么由于我们的每一个数据,的每一位是开括号或者闭括号。所以这个数据的动态生成过程就像是一个遍历二叉树的过程,我们采用递归深搜的方法。那么第二个问题,我们要知道什么时候(条件)的结点是我们要的,也即是说,我们要找出开闭括号合法的规则。我们举几个例子,比如()()(), ).....我们发现前一个可以,后一个不可以,因为闭括号开头了,再多几个例子我们发现,开闭括号的组合顺序我们不关心,只要开闭括号的相对顺序满足。
也即是:动态生成的过程中,在任何位置往前看,闭括号不能比开括号多。比如上面开头第一个是 ),就不符合规则,因为这时候开括号是0个,闭括号是1个,更多。我们自然地想到可以用一个变量,放入开括号变量就加1,放入闭括号变量就减1,变量一旦小于零就不符合要求了。
public class Solution {
StringBuilder sb = new StringBuilder();
List<String> list = new ArrayList<>();
public List<String> generateParenthesis(int n) {
helper(n, 0);
return list;
}
private void helper(int n, int t){
if(sb.length() == 2*n || t < 0){ //搜索到底(叶子节点) 或者下一个结点不满足要求,都返回。
if(sb.length() == 2*n && t == 0) //如果搜索到底而且满足要求
list.add(new String(sb));
return;
}
sb.append('(');
helper(n, t+1);
sb.deleteCharAt(sb.length()-1); //从左结点返回之后,要删除集合中的左结点。以便重新利用集合存储新遍历的结点。
sb.append(')'); //遍历右结点
helper(n, t-1);
sb.deleteCharAt(sb.length()-1);
}
}