数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
解法一:暴力解法
class Solution {
public List<String> generateParenthesis(int n) {
List<String> combinations = new ArrayList(); // 结果序列
generateAll(new char[2*n], 0, combinations); // 生成合法的括号序列
return combinations;
}
public void generateAll(char[] current, int pos, List<String> result){
if (pos == current.length){ // 当前长度达到2n时,判断是否满足条件
if (isValid(current)){
result.add(new String(current));
}
}else{
current[pos] = '(';
generateAll(current, pos+1, result);
current[pos] = ')';
generateAll(current, pos+1, result);
}
}
public boolean isValid(char[] current) { // 判断括号序列是否合法
int balance = 0;
for (char ch : current) {
if (ch == '('){
balance++;
}else{
balance--;
}
if (balance < 0){
return false;
}
}
return (balance == 0);
}
}
解法二:深搜
class Solution {
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
// 特判
if (n == 0){
return res;
}
// 进行深搜
dfs("", n, n, res);
return res;
}
/*
* @Author
* @Description
* @Date
* @Param current 当前字符串
* @Param left 剩余的左括号数
* @Param right 剩余的右括号数
* @Param res 结果集
* @return
**/
private void dfs(String current, int left, int right, List<String> res){
if (left > right){ // 递归边界:剩余左括号多于右括号,结果不合法,回溯
return;
}
if(left == 0 && right == 0){ // 递归边界:左右括号都为0,结果合法
res.add(current);
}
if (left > 0){
dfs(current+"(", left-1, right, res);
}
if (right > 0){
dfs(current+")", left, right-1, res);
}
}
}
解法三:广搜
class Solution {
class Node{ // 结点类
private String current;
private int left;
private int right;
public Node(int left, int right, String current){
this.left = left;
this.right = right;
this.current = current;
}
}
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
if (n == 0){
return res;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(new Node(n, n, ""));
while (!queue.isEmpty()){
Node curNode = queue.poll();
if (curNode.right == 0 && curNode.left == 0){
res.add(curNode.current);
}
if (curNode.left > 0){
queue.offer(new Node(curNode.left-1, curNode.right, curNode.current+"("));
}
if (curNode.right > 0 && curNode.left < curNode.right){
queue.offer(new Node(curNode.left, curNode.right-1, curNode.current+")"));
}
}
return res;
}
}