题目描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
样例
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
算法1
(DFS枚举) $O(卡特兰数)$
求组合方案,第一时间还是想到DFS枚举;
枚举过程中注意最多只能由n个左括号、n个右括号,而且保证不能出现右括号多于左括号的情况出现。
时间复杂度
参考文献
C++ 代码
class Solution {
private:
vector<string> res;
public:
vector<string> generateParenthesis(int n) {
if (n <= 0) return {};
res.clear();
string path;
dfs(n, n, n, path);
return res;
}
void dfs(const int &n, int l, int r, string &path){
if (l == 0 && r == 0){
res.push_back(path);
return;
}
if (l > 0) {
path.push_back('(');
dfs(n, l - 1, r, path);
path.pop_back();
}
if (r > 0 && l < r) {
path.push_back(')');
dfs(n, l, r - 1, path);
path.pop_back();
}
}
};
算法2
(递归枚举) $O(卡特兰数)$
人脑不擅长的事情,递归交给机器去做;
例如枚举2对括号,无非就是:
“(” + 0对括号 + “)” + 1对括号;
“(” + 1对括号 + “)” + 0对括号;
枚举3对括号就是:
“(” + 0对括号 + “)” + 2对括号;
“(” + 1对括号 + “)” + 1对括号;
“(” + 2对括号 + “)” + 0对括号;
问题规模逐渐减小,所以可以递归。
base case是 n = 0时,返回空字符串。
时间复杂度
参考文献
C++ 代码
class Solution {
public:
vector<string> generateParenthesis(int n) {
if (n <= 0) return {""};
vector<string> res;
for (int i = 0; i < n; ++i){
for (string l: generateParenthesis(i)){
for (string r: generateParenthesis(n - 1 - i)){
res.push_back("(" + l + ")" + r);
}
}
}
return res;
}
};