第二次优化成果,也不知道具体属于那种算法设计方式...(* ̄0 ̄)ノ。具体代码如下
/*
* Problem:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
* CreateTime: 2021/7/31
* Auther:Itcod/有间猫
*/
class Solution {
public:
vector<string> ans;
int length = 0;
vector<string> generateParenthesis(int n) {
if (n == 0)
return ans;
// 获得的字符串长度固定为n的两倍
length = n * 2;
// 动态申请数组
char* gc = (char*)malloc(length);
memset(gc, 0, length);
grente(gc, 0);
// 由于生成的结果与leetcode示例相反,所以把结果反过来
reverse(ans.begin(), ans.end());
free(gc);
return ans;
}
// gc: 存储生成的() c: 已经插入的次数 程序是成对插入所以边界为n
void grente(char *gc, int c) {
// 判断是否已经插入了n次
if (c == length / 2) {
// 处理成string
string res = "";
for (int j = 0; j < length; ++j)
res += *(gc + j);
ans.emplace_back(res);
return;
}
// 每次插入多是从0开始,然后向后查找为0的位置,即为空的位置
int start = 0;
for (; *(gc + start) != 0; start++);
// 在第一次出现为空的位置放置(
*(gc + start) = '(';
// 每次从相对位置0开始放置,实际位置+start,(和)直接空位置的为2*n个大小,保证之间空的位置生成的()也是成对的
for (int i = 0, end = i * 2 + 1; start + end < length && *(gc + start + end) == 0; ++i, end = i * 2 + 1) {
*(gc + start + end) = ')';
grente(gc, c + 1);
// 恢复现场
*(gc + start + end) = 0;
}
*(gc + start) = 0;
}
};
第一次ac的做法暴力枚举(⊙ˍ⊙)
代码也贴下,相对于第一次,第二次优化了好多啊啊┗|`O′|┛ 嗷~~
class Solution {
public:
vector<string> ans;
vector<string> generateParenthesis(int n) {
if (n == 0)
return ans;
vector<char> r;
dfs("", r, n * 2, n, n);
return ans;
}
void push(vector<char>& role, char c) {
if (role.size()) {
char en = role.back();
if (en == '(' && c == ')') {
role.pop_back();
return;
}
}
role.emplace_back(c);
}
void dfs(string str, vector<char> role, int c, int l, int r) {
if (c == 0) {
if (role.size() == 0) {
ans.emplace_back(str);
return;
}
return;
}
vector<char> temp = role;
if (l > 0) {
push(role, '(');
dfs(str + '(', role, c - 1, l - 1, r);
}
if (r > 0) {
push(temp, ')');
dfs(str + ')', temp, c - 1, l, r - 1);
}
}
};