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(n-1)+ ')' , '()' +f(n-1) , f(n-1)+ '()' } ,但是发现,当n=4时,该方法将不能涵盖 "(())(())" 。我想,这不就是f(2)+f(2)吗?既然这样,我就可以将f(4)分为 f(1)+f(3), f(2)+f(2),f(3)+f(1),但是这样的话又不能涵盖(((()))),因此我又要加上 '(' +f(3)+ ')' 这个情况。下面是我的代码,使用map是为了避免重复计算f(n)。使用hashSet是避免出现重复的字符串。
package leetcode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class Generate_Parentheses_22 {
HashMap<Integer, List<String>> map=new HashMap<Integer, List<String>>();
public List<String> generateParenthesis(int n) {
List<String> list=new ArrayList<String>();
if(n==0){
list.add("");
return list;
}
if(n==1){
list.add("()");
return list;
}
if(map.get(n)!=null){
return map.get(n);
}
HashSet<String> hashSet=new HashSet<String>();
List<String> n_1_Paenthesis=generateParenthesis(n-1);
for(String s:n_1_Paenthesis){
hashSet.add("("+s+")");
}
for(int left=1;left<=n-1;left++){
List<String> left_Paenthesis=generateParenthesis(left);
int right=n-left;
List<String> right_Paenthesis=generateParenthesis(right);
for(String ls:left_Paenthesis){
for(String rs:right_Paenthesis){
hashSet.add(ls+rs);
}
}
}
for(String s:hashSet){
list.add(s);
}
map.put(n, list);
return list;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Generate_Parentheses_22 g=new Generate_Parentheses_22();
List<String> list=g.generateParenthesis(4);
for(String s:list){
System.out.println(s);
}
}
}
大神使用的递归方法十分简洁厉害:
思路是从左到右往字符串里加 '(' 和 ')' 。left中存储剩余的左括号个数,right中存储剩余的右括号个数,我们只需要在添加过程中保证 “剩余的左括号个数” 小于 “剩余的右括号个数”,即 ”已添加的左括号个数“ 大于 ”已添加的右括号个数“ 。
public List<String> generateParenthesis(int n) {
List<String> result = new LinkedList<String>();
if (n > 0)
generateParenthesisCore("", n, n, result);
return result;
}
private void generateParenthesisCore(String prefix, int left, int right, List<String> result) {
if (left == 0 && right == 0)
result.add(prefix);
// Has left Parenthesis
if (left > 0)
generateParenthesisCore(prefix + '(', left - 1, right, result);
// has more right Parenthesis
if (left < right)
generateParenthesisCore(prefix + ')', left, right - 1, result);
}