思路
思路1: 动态规划
思路2:DFS
代码(C++)
思路1: 动态规划
class Solution {
public:
vector<string> generateParenthesis(int n) {
// 动态规划
if(n == 0){
return {};
}
if(n == 1){
return {"()"};
}
vector<vector<string>> dp(n+1);
dp[0] = {""};
dp[1] = {"()"};
string str;
for(int i = 2; i <= n; i++){ // dp从0开始,一直到n
for(int j = 0; j < i; j++){
for(string p : dp[j]){ // p+q=n-1
for(string q: dp[i-j-1]){ // p+q=n-1 这里的i就是式子里的n
str = "(" + p + ")" + q;
dp[i].push_back(str);
}
}
}
}
return dp[n];
}
};
思路2: DFS + 剪枝
// 剩余n个可用
class Solution {
public:
vector<string> generateParenthesis(int n) {
if(n == 0){
return {};
}
vector<string> res;
DFS("", n, n, res); //左边剩余n个可用,右边剩余n个可用
return res;
}
void DFS(string curStr, int left, int right, vector<string>& res){
if(left == 0 && right == 0){ //分支完成
res.push_back(curStr);
return;
}
if(left > right){ // 剪枝 左边剩余可用的大于右边剩余可用的
return;
}
if(left > 0){
DFS(curStr + "(", left-1, right, res);
}
if(right > 0){
DFS(curStr + ")", left, right-1, res);
}
}
};
// 已用0个
class Solution {
public:
vector<string> generateParenthesis(int n) {
if(n == 0){
return {};
}
vector<string> res;
DFS("", 0, 0, n, res); //左边已用0个,右边已用0个
return res;
}
void DFS(string curStr, int left, int right, int &n, vector<string>& res){
if(left == n && right == n){ //分支完成
res.push_back(curStr);
return;
}
if(left < right){ // 剪枝 左边已用的个数 小于 右边左边已用的个数
return;
}
if(left < n){
DFS(curStr + "(", left+1, right, n, res);
}
if(right < n){
DFS(curStr + ")", left, right+1, n, res);
}
}
};