请你写一个算法,输入是一个正整数 n
,输出是 n
对儿括号的所有合法组合,
比如说,输入 n=3
,输出为如下 5 个字符串:
"((()))", "(()())", "(())()", "()(())", "()()()"
C++:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
// 可用的左括号数量为 left 个,可用的右括号数量为 rgiht 个
void backtrack(int left, int right, string& track, vector<string>& res)
{
// 若左括号剩下的多,说明不合法
if (right < left) return;
// 数量小于 0 肯定是不合法的
if (left < 0 || right < 0) return;
// 当所有括号都恰好用完时,得到一个合法的括号组合
if (left == 0 && right == 0) {
res.push_back(track);
return;
}
// 尝试放一个左括号
track.push_back('('); // 选择
backtrack(left - 1, right, track, res);
track.pop_back(); // 撤消选择
// 尝试放一个右括号
track.push_back(')'); // 选择
backtrack(left, right - 1, track, res);
track.pop_back(); // 撤消选择
}
vector<string> generateParenthesis(int n) {
// 记录所有合法的括号组合
vector<string> res;
if (n == 0)
return res;
// 回溯过程中的路径
string track;
// 可用的左括号和右括号数量初始化为 n
backtrack(n, n, track, res);
return res;
}
void main()
{
vector<string> res;
res = generateParenthesis(3);
for (int i=0;i<res.size();i++)
{
cout << res[i] << endl;
}
}
Java:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Solution01 {
public int generateParenthesis(int n) {
List<String> res = new ArrayList<>();
// 特判
if (n == 0) {
return res.size();
}
// 执行深度优先遍历,搜索可能的结果
dfs("", n, n, res);
return res.size();
}
/**
* @param curStr 当前递归得到的结果
* @param left 左括号还有几个没有用掉
* @param right 右边的括号还有几个没有用掉
* @param res 结果集
*/
private void dfs(String curStr, int left, int right, List<String> res) {
// 因为是递归函数,所以先写递归终止条件
if (left == 0 && right == 0) {
res.add(curStr);
return;
}
// 因为每一次尝试,都使用新的字符串变量,所以没有显式的回溯过程
// 在递归终止的时候,直接把它添加到结果集即可,与「力扣」第 46 题、第 39 题区分
// 如果左边还有剩余,继续递归下去
if (left > 0) {
// 拼接上一个左括号,并且剩余的左括号个数减 1
dfs(curStr + "(", left - 1, right, res);
}
// 什么时候可以用右边?例如,((((((),此时 left < right,
// 不能用等号,因为只有先拼了左括号,才能拼上右括号
if (right > 0 && left < right) {
// 拼接上一个右括号,并且剩余的右括号个数减 1
dfs(curStr + ")", left, right - 1, res);
}
}
public static void main(String[] args) {
Solution01 s1 = new Solution01();
Scanner input = new Scanner(System.in);
int n = input.nextInt();
System.out.println(s1.generateParenthesis(n));
}
}
Python
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
def backtrack(left,right,sub_res):
if left == 0 and right ==0:
res.append("".join(sub_res[:]))
return
if left > right or left < 0 or right < 0:
return
sub_res.append('(')
backtrack(left-1,right,sub_res)
sub_res.pop()
sub_res.append(')')
backtrack(left,right-1,sub_res)
sub_res.pop()
backtrack(n,n,[])
return res