LeetCode 22 Generate Parentheses 卡特兰数问题,有待进一步学习

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常量池的原理所致。整个算法值得记忆。


你可能感兴趣的:(LeetCode 22 Generate Parentheses 卡特兰数问题,有待进一步学习)