[LeetCode] 22_括号生成
题目要求
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
题目分析
- 这道题可以用递归地排列组合来做,但有一个限制条件,就是要求是“有效的”组合。
- 怎么定义有效?
因为题目中只有一种括号(感觉进阶版可以列出多种括号),并且左右括号的数目一定是一样的,所以有效的要求是不能一个右括号前的左括号数一定大于等于它。因为题目中只有一种括号(感觉进阶版可以列出多种括号),并且左右括号的数目一定是一样的,所以有效的要求是不能一个右括号前的左括号数一定大于等于它。 - 如何判定有效?
一般有两种方式:一是一般有两种方式:一是在组合完成后判定,二是在组合过程中判定(或不产生无效的组合)。在这里显然如果能找到一种办法在只产生有效的组合,效率比较高。那么又回归到了有效性的定义上。 - 接下来就是递归方式的选择,递归一般的形式如下:
递归结束条件:
选择1:
选择2:
选择3:
……
选择n: - 这里,递归结束条件是左右括号都已经用完,这是将str加入到结果数组中。递归选择1:剩余左括号数>0,则用掉一个左括号;递归选择2:剩余左括号数小于剩余右括号数,则用掉一个右括号。
注意点
怎样设定递归选择条件。
当左括号有剩余的时候,一定可以用左括号。
当右括号有剩余的时候,只有已经用掉的左括号数大于已经用掉的右括号数时,才能使用右括号。
代码
class Solution {
public:
void backtrade(string str,vector<string>& res,int left,int right){
if(left==0 && right==0){
res.push_back(str);
return;
}
if(left>0){
backtrade(str+"(",res,left-1,right);
}
if(left<right){
backtrade(str+")",res,left,right-1);
}
}
vector<string> generateParenthesis(int n) {
vector<string>res;
backtrade("",res,n,n);
return res;
}
};