(Java)LeetCode-22. 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:

"((()))", "(()())", "(())()", "()(())", "()()()"



这道题挺难的,感觉做出来不容易呀。 我最开始是用了递归的想法,求f(n)的时候分成f(1)和f(n-1)排列组合,f(2)和f(n-1)排列组合,直到f(n-1)和f(1)排列组合,最后加上f(n-1)所有的情况最外面再套上一对括号,这里面会有一些重复情况出现,所以我采用Set方法去重。同时,求f(n)的时候回求很多次的f(n-1),f(n-2)...浪费时间,就像用递归求斐波那契数列一样,所以我采用了一个数组来存放已经求过的f(n),这样将时间从20ms缩短到了5ms,代码如下:

public class Solution {

	List<?>[] ans = new ArrayList<?>[100];
	boolean flag = false;
	int N = 1;
	public List<String> generateParenthesis(int n) {
        if(n <= N){
			if( n == 1 && flag == false){
        	List<String> list = new ArrayList<String>();
			list.add("()");
			ans[N++] = list;
			flag = true;
			return list;
			}
			else
				return (List<String>)ans[n];
		}
        Set<String> set = new HashSet<String>();		
		for(int i = 0 ; i < n ; i++){
			if(i == 0){
				for(String ss : generateParenthesis(n-1)){
					set.add("("+ss+")");
				}
			}else{
				for(String ss : generateParenthesis(i)){
					for(String aa : generateParenthesis(n-i)){
					set.add(ss+aa);
					}
				}
			}
		}
		if(N == n){
			ans[N++] = new ArrayList<String>(set);
		}
		return new ArrayList<String>(set);
    }
    
    public static void main(String[] args){
    	Solution sol = new Solution();
    	System.out.println(sol.generateParenthesis(3));
    }
}

而后,本着自创的当然不是最优的原则,上网看了看别人的解法,好厉害。用的是深度优先搜索,也是递归。

其实我的第一直觉也是采用深度优先搜索,不过之前不知道怎么编程实现,也没有想到这个专有名词。

思路如下:

对一个长度为2n的合法排列,第1到2n个位置都满足如下规则:左括号的个数大于等于右括号的个数。所以,我们就可以按照这个规则去打印括号:假设在位置k我们还剩余left个左括号和right个右括号,如果left>0,则我们可以直接打印左括号,而不违背规则。能否打印右括号,我们还必须验证left和right的值是否满足规则,如果left>=right,则我们不能打印右括号,因为打印会违背合法排列的规则,否则可以打印右括号。如果left和right均为零,则说明我们已经完成一个合法排列,可以将其打印出来。通过深搜,我们可以很快地解决问题

链接是:http://blog.csdn.net/yutianzuijin/article/details/13161721


这个思路是很重要的,可以遍历出所有可能性,而且不会有重复,速度很快,只用了2ms,要掌握这个解法。代码如下,很简洁:

public class Solution {

	public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<String>();
        generating(n,n,"",res);
		return res;
    }
    
    private void generating(int left, int right, String str, List<String> res) {
		
    	if(left == 0 && right == 0){
    		res.add(str);
    	}
    	if(left > 0){
    		generating(left-1,right,str+"(",res);
    	}
    	if(left<right){
    		generating(left,right-1,str+")",res);
    	}		
	}

	public static void main(String[] args){
    	Solution sol = new Solution();
    	System.out.println(sol.generateParenthesis(3));
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值