题目描述:
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
我的思路如下:
发现规律没?为什么要再最后减去一个
n
个
"
(
)
"
n个"()"
n个"()" 的操作呢?因为
(
)
S
(
n
−
1
)
和
S
(
n
−
1
)
(
)
()S(n-1)和S(n-1)()
()S(n−1)和S(n−1)()都含有
n
个
"
(
)
"
n个"()"
n个"()" ,因此需要减掉一个。
最后对这个得到的字符串数组进行排序,就能得到结果。
代码如下:
vector<string> generateParenthesis(int n){
vector<string> temp;
temp.push_back("()");
if(n == 1) return temp;
for(int i = 1; i < n; i++){
int k = temp.size();
for(int j = 0; j < k; j++){
temp.push_back("(" + temp[j] + ")");
temp.push_back("()" + temp[j]);
temp.push_back(temp[j] + "()");
}
temp.erase(temp.begin(), temp.begin() + k); //删除S(i)的结果,留下S(i+1)的结果
temp.pop_back(); //删除一个“ n个"()" ”
}
sort(temp.begin(), temp.end()); //对结果排序
return temp;
}
该结果在n<=3是没问题的,但是一旦n>=4就会出错!
为什么会这样?
我们来看:当 n = 3 n=3 n=3的时候,包含了 “()(())” 和 “(())()”,因此当 n = 4 n=4 n=4的时候, “()S(3)” 和 "S(3)n"同样会出现两个 “()(())()” !所以我的想法是错的(害!!!)。
既然错了,那我们看看官方是怎样写的?
官方的顺序可以用一个二叉树的结构来表示:
上图来自该题精选答案的作者@liweiwei1419
利用深搜加剪枝的方法来得到结果,这样得到的结果与测试用例的结果顺序是一样的。代码如下:
/*
curStr 当前递归得到的结果
left 左括号有几个
right 右括号有几个
n 左右个需要n个才能满足条件
res 结果集
*/
void dfs(string curStr, int left, int right, int n, vector<string>& strs){
if(left == n && right == n){
strs.push_back(curStr);
return;
}
//剪枝
if(left < right){
return;
}
if(left < n){
dfs(curStr + "(", left + 1, right, n, strs);
}
if(right < n){
dfs(curStr + ")", left, right + 1, n, strs);
}
}
vector<string> generateParenthesis(int n){
vector<string> res;
if(n == 0)return res;
dfs("", 0, 0, n, res);
return res;
}
不得不说,这类题考察的思路很清奇,正好也可以补一下自己的薄弱点。
题目来自leetcode,点击题目描述即可跳转到题目页面