给定一个数字n,生成包含2n括号的合法序列
n=3
[((())), (()()), (())(), ()(()), ()()()]
暴力法
public List<String> generateParenthesis(int n ){
List<String> res=new ArrayList<>();
generateAll(new char[n*2],res,0);
return res;
}
private void generateAll(char[] chars, List<String> res,int pos) {
if (pos==chars.length){
if (isVaild(chars)){
res.add(new String(chars));
}
return;
}
chars[pos]='(';
generateAll(chars,res,pos+1);
chars[pos]=')';
generateAll(chars,res,pos+1);
}
//判断括号是否合法
private boolean isVaild(char[] chars) {
int balance=0;
for (char value : chars) {
if (value=='(') {
balance++;
}else {
balance--;
}
if (balance<0) return false;
}
return balance==0;
}
回溯剪枝
/**
* 如果左括号数量不大于 nn,我们可以放一个左括号。
* 如果右括号数量小于左括号的数量,我们可以放一个右括号。
* 剪枝操作
*/
public List<String> generateParenthesis2(int n){
List<String> res=new ArrayList<>();
backTrack(res,new StringBuilder(),0,0,n);
return res;
}
private void backTrack(List<String> res, StringBuilder stringBuilder, int open, int close, int max) {
if (stringBuilder.length()==max*2){
res.add(stringBuilder.toString());
return;
}
if (open<max){
stringBuilder.append("(");
backTrack(res,stringBuilder,open+1,close,max);
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
if (close<open){
stringBuilder.append(")");
backTrack(res,stringBuilder,open,close+1,max);
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
}