题目描述:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[ "((()))",
"(()())",
"(())()",
"()(())",
"()()()" ]
思路:回溯
具体详见代码所示:
class Solution {
List<String> res=new ArrayList<>();
public List<String> generateParenthesis(int n) {
String s="";
huisu(s,n,n);
return res;
}
public void huisu(String s,int l,int r){
if(l==0&&r==0){
res.add(s);
return;
}
if(l>0){
huisu(s+"(",l-1,r);
}
if(r>l){
huisu(s+")",l,r-1);
}
}
}
但是,我一开始是用的StringBuffer来做这道题:
class Solution {
List<String> res=new ArrayList<>();
public List<String> generateParenthesis(int n) {
StringBuffer s=new StringBuffer();
huisu(s,n,n);
return res;
}
public void huisu(StringBuffer s,int l,int r){
if(l==0&&r==0){
res.add(s.toString());
return;
}
if(l>0){
huisu(s.append("("),l-1,r);
}
if(r>l){
huisu(s.append(")"),l,r-1);
}
}
}
与上述代码相比,就是把String换成了StringBuffer;但是当n为3时,使用Stringbuffer的输出结果确是:
["((()))","((())))())","((())))()))()","((())))()))())(())","((())))()))())(()))()"]
正确答案为:
["((()))","(()())","(())()","()(())","()()()"]
以下为我画的当得到第一个结果之后,String与StringBuffer分别回溯的下一步结果。
为什么会出现这种情况,那就来看看String与StringBuffer的区别;
StringBuffer是使用缓冲区的,其声明的对象内容是可以改变的,而String声明之后,其内容是不可改变的,改变的只是其内存的指向;
也就是说,当StringBuffer类型的 s执行s.append("a");s还是以前的那个s,但是值发生了改变,回溯不回去以前的值了。
而String类型的s执行s+"a"时,此时就会产生一个新的String变量,与之前的那个s无关,故可以回溯回去。