给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[ "((()))", "(()())", "(())()", "()(())", "()()()" ]
解题思路:使用递归
广度优先搜索方式
所谓广度优先搜索的方式就是尽可能早的先输出完整的括号对(), 也就是当输出一个左括号 '(' , 尽可能先输出一个右括号 ‘)’ 。
广度优先搜索的目的是先得到完整的括号对(), 这种情况下需要需要考虑如下两种情况:
①输出右边括号')'的时机:如果剩余的右括号数大于剩余的左括号数,那么意味着之前已经有一个左括号输出了,在这种情况下,将当前存放的括号组合情况添加一个右括号,然后剩余右边括号数减1,然后继续递归调用。
②输出左边括号'('的时机:如果剩余的左括号数leftCount大于0,则当前存放的括号组合情况添加一个左括号'(', 然后剩余左括号数减1,然后继续递归调用。基于上面两种情况,使用递归
public List<String> generateParenthesis(int n) {
/* 用0和1来表示左右括号,0是左括号,1是右括号
* (()) 0 0 1 1√
* ()() 0 1 0 1√
* ())( 0 1 1 0
* )(() 1 0 0 1
* )()( 1 0 1 0
* ))(( 1 1 0 0
* */
List<String> list = new ArrayList<String>();
int left = n; //左括号的剩余数量
int right = n; //右括号的剩余数量
//组合方案:只要还有左括号,就优先加入左括号,
// 如果有右括号而且右括号的剩余数量比左括号多,这个时候可以加入右括号
//考虑使用递归,传入4个参数:当前list,当前字符串,左括号剩余数量,右括号剩余数量
String cu = "";//存放当前字符串
digui(list ,cu, left, right);
return list;
}
public void digui(List<String> list, String cu,int left ,int right){
/**
* 结束条件:
* 当剩余括号数和剩余右括号数都为0时,表示括号已经用完,这个时候结束递归,直接输出就可以打印出一种情况
*/
if (left == 0 && right == 0) {
// System.out.println(cu);
list.add(cu);//将字符串输入
}
//如果还有剩余左括号数,则将当前存放的括号组合情况添加一个左括号,然后剩余左边括号数减1,然后递归调用
if(left > 0){
digui(list,cu+"(",left-1,right);
}
//剩余的右括号数大于剩余的左括号数,说明此刻已经有一个左括号输出了,在这种情况下,可以添加一个右括号,然后右边括号数减1,递归调用
if(right > 0 && left < right){
digui(list,cu+")",left,right-1);
}
}
public static void main(String[] args) {
int n = 2;
List<String> list = generateParenthesis(n); // 生成n对括号的所有组合
System.out.println(list);
// for(String str : list){
// System.out.println(str);
// }
}