题目描述
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
优秀题解
法一
- DFS,回溯
- 重点是维护nl(左括号可以使用的数量)和nr(右括号可以使用的数量)
- 代码比较巧妙
都可以使用时,先使用左括号
随着左括号的使用,右括号可以使用的数量才逐渐增加
- 函数地地址引用,第一次见,在这种回溯算法中比较好用
vector<string> generateParenthesis(int n) {
if(n==0){
return {};
}
vector<string> res;
dfs(res,"",n,0);
return res;
}
void dfs(vector<string>& res,string s, int nl, int nr){
if(nl==0&&nr==0){
res.push_back(s);
}else{
if(nl>0){
dfs(res,s+"(",nl-1,nr+1);
}
if(nr>0){
dfs(res,s+")",nl,nr-1);
}
}
}
法二
- 动态规划
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<vector<string>> dp;
vector<string> dp0;
dp0.push_back("");
if(n==0) {
//vector<string> dp0;
// dp0.push_back("");
return dp0;
}
dp.push_back(dp0);
int i,j;
for(i=1;i<=n;i++){
// printf("i=%d\n",i);
vector<string> dpn;
for(j=0;j<i;j++){
// printf("j=%d\n",j);
vector<string> str1 = dp[j];
vector<string> str2 = dp[i-1-j];
for (string s1 : str2) {
//printf("a\n");
for (string s2 : str1) {
// printf("b\n");
dpn.push_back("("+s1+")"+s2);
}
}
}
dp.push_back(dpn);
}
return dp[n];
}
};