Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
解题思路:这个是个非常好的递归问题,括号匹配本质上是卡特兰数问题,网上有丰富的资料讲解这个问题,关于这个问题,以后还会继续学习,现在我们来解决目前这个括号的问题。
首先,我想到一个递推方案,记(XX)为n-1个匹配好的括号,按照一至三对括号的匹配方案,可知有如下递归关系,()(XX) (XX)() ((XX)),按照这个思路算法如下,可是现实狠狠的打了我的脸,当n=4的时候,(())(())这个结果并不在集合中,显然双括号匹配的方案不能得到完全解,并且效率非常低。
List<String> res = new ArrayList<String>();
public List<String> generateParenthesis(int n) {
gene1(n,n,"");
return res;
}
public void gene1(int l,int r,String str){
if(l==0&&r==0){
if(!res.contains(str))
res.add(str);
return;
}
//中
StringBuffer sb = new StringBuffer(str);
sb.insert(0, "(");
sb.insert(sb.length(), ")");
String temp = sb.toString();
gene1(l-1,r-1,temp);
//左
StringBuffer sb1 = new StringBuffer(str);
sb1.insert(0, "()");
String temp1 = sb1.toString();
gene1(l-1,r-1,temp1);
//右
StringBuffer sb2 = new StringBuffer(str);
sb2.insert(str.length(), "()");
String temp2 = sb2.toString();
if(!(temp2.charAt(0)=='('&&temp2.charAt(1)==')')){
gene1(l-1,r-1,temp2);
}
}
通过·学习网上的资料,找到了一个非常简明的单括号匹配法则,按照左右括号匹配,当左括号小于右括号时,添加右括号。整个算法非常简易,但是数学上的理解还需要深入。
代码如下:
List<String> res = new ArrayList<String>();
public List<String> generateParenthesis(int n) {
gene1(n,n,"");
return res;
}
public void gene(int l,int r,String str){
if(l==0&&r==0){
res.add(str);
return ;
}
if(l>0){
gene(l-1,r,str+"(");
}
if(r>l){
gene(l,r-1,str+")");
}
}
实在是太精妙了,而且完全不需要担心括号匹配导致的字符串被覆盖的问题,每次递归都是复制新的实参,这也是java string常量池的原理所致。整个算法值得记忆。