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));
}
}