常规的方法是用回溯来写这个题,但是回溯理解起来实在是有一点困难,下面这个思路是直接用递归来生成,首先要明确的是,在已经生成的字符串中,左括号的数量一定要大于等于右括号的数量,否则就不合法,因此本题只会存在两个分支:
- 当左括号数量 == 右括号数量时:只能加入做括号
- 当左括号数量 > 右括号数量时:可以加入做括号,也可以加入右括号,但是要先左后右。并且,当左括号数量已经足够之后,只加入右括号即可。
left和right分别表示剩余的左右括号的数量,因此,base case是两者都为0时,此时要将此次生成的字符串保存到结果中
List<String> re;
public List<String> generateParenthesis(int n) {
re=new LinkedList();
generate(n,n,"");
return re;
}
void generate(int left, int right, String s){
if(left==0 && right==0){
// 左括号有n个,右括号也有n个
re.add(s);
return;
}
if(left==right){
generate(left-1,right,s+"(");// 左右括号数量相等时,只能加入左括号
}else if(left<right){ // 如果左括号数量 > 右括号数量
if(left>0){
// 如果左括号数量不足,先压入左括号,再压入右括号
generate(left-1,right,s+"(");
} // 如果左括号数量已经够了,直接压入右括号
generate(left,right-1,s+")");
}
// 不可能存在left>right的情况,此时已选中的左括号数量小于已选中的右括号数量 不合法
}
这个方法思路清晰明确,比回溯好理解很多