题目描述:
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
学习记录:
看到的第一想法是,用递归和回溯,就和那个电话号码题差不多,但苦鲁西,但是我写不出来鸭!
题解是暴力法、回溯法、按括号长度递归法,emmm,都看不懂
后面有个dl的解题思路让我豁然开朗:
1.
class Solution {
List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {
if(n <= 0){
return res;
}
getParenthesis("",n,n);
return res;
}
private void getParenthesis(String str,int left, int right) {
if(left == 0 && right == 0 ){
res.add(str);
return;
}
if(left == right){
//剩余左右括号数相等,下一个只能用左括号
getParenthesis(str+"(",left-1,right);
}else if(left < right){
//剩余左括号小于右括号,下一个可以用左括号也可以用右括号
if(left > 0){
getParenthesis(str+"(",left-1,right);
}
getParenthesis(str+")",left,right-1);
}
}
}
2.
class Solution {
public:
vector<string> generateParenthesis(int n) {
dfs("", n, n);
return res;
}
private:
vector<string> res;
void dfs(const string& str, int left, int right) {
//第一个if,就是剪枝条件,不满足的分支直接return
if (left < 0 || left > right) // 出现类似 ()) )) 这种格式都是错误的不用再继续了
return;
//满足条件的叶子加入容器
if (left == 0 && right == 0) {
res.push_back(str);
return;
}
//所有可能情况我都便利,但是不满足条件的都会被剪枝
dfs(str + '(', left - 1, right);
dfs(str + ')', left, right - 1);
}
};
其实这两种思路都是差不多的,但是都很清晰,我简直依托答辩
看看dl,提升自己,DF&,加油加油,努力
try1:在之后的一天来写这个代码,四不像
我想判断字符串的长度等于我们要求的就好,但是这样没有办法来计算这种情况n=3,((((这样的...所以我想到了要加入left和right来记录左右的个数,但是这样length和i就没啥用了,所以还是不是特别会剪枝法
try2:在之后的一天来写这个代码,成功!虽然多判断了right<0,但显然当时我没想到
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> result;
string s="";
find(result,s,'(',n-1,n);
return result;
}
void find(vector<string>& v,string s,char c,int left,int right)
{
s+=c;
if(left==0 && right==0)
{
v.push_back(s);
}
else if(left>right || left<0 || right<0)
{
return;
}
find(v,s,'(',left-1,right);
find(v,s,')',left,right-1);
}
};