数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处
继昨天归纳了回溯的一些题目之后,今天又重新做了一下“括号生成”,有新的感觉。
void kuohaoDFS(int left,int right,string temp, vector<string>& ret) {
//剪枝(应该是没那机会了)
if (left > right)
return;
//返回条件
if (left == 0 && right == 0) {
ret.push_back(temp);
return;
}
//如果有左括号
if (left > 0) {
temp.push_back('(');
left-=1;
kuohaoDFS(left, right, temp , ret);
}
//如果有右括号
if (right > 0) {
temp.push_back(')');
right-=1;
kuohaoDFS(left, right, temp , ret);
}
}
vector<string> kuohao(int n) {
vector<string> ret;
kuohaoDFS(n, n,"",ret);
return ret;
}
果不其然,失败了。
我觉得是因为left-1和right-1放早了,就像二叉树的谦虚遍历,也没见先root = root->left之后再传root为参的。
因为调试一下之后发现:当回溯的时候,对于括号数量的计数总会多一个出来,于是我就修改了代码。
void kuohaoDFS(int left,int right,string temp, vector<string>& ret) {
//剪枝(应该是没那机会了)
if (left > right)
return;
//返回条件
if (left == 0 && right == 0) {
ret.push_back(temp);
return;
}
//如果有左括号
if (left > 0) {
temp.push_back('(');
//left-=1;
kuohaoDFS(left-1, right, temp , ret);
}
//如果有右括号
if (right > 0) {
temp.push_back(')');
//right-=1;
kuohaoDFS(left, right-1, temp , ret);
}
}
vector<string> kuohao(int n) {
vector<string> ret;
kuohaoDFS(n, n,"",ret);
return ret;
}
修改之后,还是没能彻底解决问题我就想,是不是因为字符串的问题,因为在函数进入下一层的时候,状态就已经被改变了,所以回退之后是回退到状态改变之后的样子,就引起了断层。
于是我又改了代码。
void kuohaoDFS(int left,int right,string temp, vector<string>& ret) {
//剪枝(应该是没那机会了)
if (left > right)
return;
//返回条件
if (left == 0 && right == 0) {
ret.push_back(temp);
return;
}
//如果有左括号
if (left > 0) {
kuohaoDFS(left - 1, right,temp+'(',ret);
}
//如果有右括号
if (right > 0) {
kuohaoDFS(left, right - 1,temp+')',ret);
}
}
vector<string> kuohao(int n) {
vector<string> ret;
kuohaoDFS(n, n,"",ret);
return ret;
}
这个版本终于是稳定了。
后来我想了好久,确实就是二叉树的便利,剪枝,并读取叶子节点的内容。
不一样的是在遍历的过程中要对树进行构造。
我又想了其他的题目,其他题目就是对多叉树的遍历,或取叶子,或取路径,或每个节点都要。
【回溯算法】从入门到入土,七道试题精选、精讲、精练