数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
复杂度:n 2^(2n) n
public List<String> generateParenthesis(int n){
// 可将res设置为全局变量,调用generateAll函数对res做操作,再在主函数返回res结果
List<String> res = new ArrayList<>();
char[] cur = new char[2 * n];
generateAll(cur, 0, res);
return res;
}
// 递归生成所有可能的括号。
// pos标记。记录什么时候结束
public void generateAll(char[] cur, int pos, List<String> res){
if(pos == cur.length) {
if(vaild(cur)) res.add(new String(cur));
} else {
cur[pos] = '(';
generateAll(cur, pos + 1, res);
cur[pos] = ')';
generateAll(cur, pos + 1, res);
}
}
public boolean vaild(char[] cur){
// 栈的一种特殊情况。
int cnt = 0;
for(char c : cur){
if(c == '(') cnt++;
else cnt--;
if(cnt < 0) return false;
}
return cnt == 0;
}
和下标有关的使用字符数组,和添加删除字符使用StringBuffer
回溯法
复杂度:
public List<String> generateParenthesis(int n){
List<String> res = new ArrayList<>();
backtrack(res, new StringBuffer(), 0, 0, n);
return res;
}
public void backtrack(List<String> res, StringBuffer cur, int open, int close, int n){
if(cur.length() == 2 * n){
res.add(cur.toString());
return;
}
if(open < n){
cur.append('(');
backtrack(res, cur, open + 1, close, n);
cur.deleteCharAt(cur.length() - 1);
}
if(close < open){
cur.append(')');
backtrack(res, cur, open, close + 1, n);
cur.deleteCharAt(cur.length() - 1);
}
}