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: "((()))", "(()())", "(())()", "()(())", "()()()"
又是把所有满足条件的结果存到一个ArrayList里面, 之前也有类似的如Letter combination of a Phone Number这道题。这种类型的题其实形成了一个套路,套路就是,recursion参数包括最终结果的集合(ArrayList),input(String),递归层次level(int),某一条具体的路径Path
1 public class Solution { 2 public ArrayList<String> generateParenthesis(int n) { 3 ArrayList<String> res = new ArrayList<String>(); 4 int numleftp = n; 5 int numrightp = n; 6 generate(res, "", n, numleftp, numrightp); 7 return res; 8 } 9 public void generate(ArrayList<String> res, String singlecase, int n, int numleftp, int numrightp) { 10 if (singlecase.length() == 2 * n) { 11 res.add(singlecase); 12 return; 13 } 14 if (singlecase.length() == 0) { 15 singlecase += "("; 16 numleftp--; 17 generate(res, singlecase, n, numleftp, numrightp); 18 } 19 else { 20 if (numleftp > 0) { 21 singlecase += "("; 22 numleftp--; 23 generate(res, singlecase, n, numleftp, numrightp); 24 singlecase = singlecase.substring(0, singlecase.length()-1); 25 numleftp++; 26 } 27 if (numrightp > numleftp) { 28 singlecase += ")"; 29 numrightp--; 30 generate(res, singlecase, n, numleftp, numrightp); 31 singlecase = singlecase.substring(0, singlecase.length()-1); 32 numrightp++; 33 } 34 } 35 } 36 }
另一个人的类似解法:(摘自伪技回忆录)
1 public class Solution { 2 public ArrayList<String> generateParenthesis(int n) { 3 ArrayList<String> res = new ArrayList<String>(); 4 if(n==0) { 5 res.add(""); 6 return res; 7 } 8 9 helper(n,0,0,res,""); 10 return res; 11 } 12 13 public void helper(int n, int left, int right, ArrayList<String> res, String temp){ 14 // exit: all ( appeared 15 if(left == n){ 16 for (int i=0; i<n-right; i++) 17 temp = temp + ")"; 18 res.add(temp); 19 return; 20 } 21 22 // case1: number of ( > number of ) 23 if(left>right){ 24 helper(n, left+1, right, res, temp + "("); 25 helper(n, left, right+1, res, temp + ")"); 26 } 27 28 // case2: number of ( == number of ) 29 else helper(n, left+1, right, res, temp + "("); 30 } 31 }
这道题也解决了我语法上的一个疑惑,那就是java的嵌套函数到底是不是在原始参数上进行修改?函数内的运行对参数的改变是否会对函数外同名参数造成改变?
答案是:不是的,参数送进函数之后,其实是另外开辟了一片空间,拷贝了这个参数,用那个参数进行运算,其结果并不会影响原来函数外的参数。比如别人这段程序里的24, 25行,temp+"("被赋给了helper函数的temp参数,该层函数的temp变量其实并没有发生改变,所以不需要让temp把 “(” 删了再去尝试temp加上 “)” 这另一种可能。至于我的程序为什么需要让temp删掉“(”再去加上“)”,是因为我在这层函数里对temp的值进行了改变,所以在尝试新的可能之前需要把temp改回来。
Code Ganker的做法,高手的代码就是简洁啊
1 public ArrayList<String> generateParenthesis(int n) { 2 ArrayList<String> res = new ArrayList<String>(); 3 if(n<=0) 4 return res; 5 helper(n,n,new String(),res); 6 return res; 7 } 8 private void helper(int l, int r, String item, ArrayList<String> res) 9 { 10 if(r<l) 11 return; 12 if(l==0 && r==0) 13 { 14 res.add(item); 15 } 16 if(l>0) 17 helper(l-1,r,item+"(",res); 18 if(r>0) 19 helper(l,r-1,item+")",res); 20 }