Leetcode22: 括号生成(递归)
方法1:暴力解法
难点:
递归的生成所有的括号(递归算法)
generateAll(current, 0, combinations) current:当前字符数组, pos:当前写入括号的位置, combinations:当前所有合法的长度为2n的集合判断括号是否合法
遍历字符数组,遇到'(', i++, 遇到‘)’, i--; 如果括号合法,i应该是0
class Solution { public ListgenerateParenthesis(int n) { List combinations = new ArrayList ();//存放合法括号的集合 char[] current = new char[2*n]; //存放当前括号字符数组 generateAll(current, 0, combinations);//递归函数 return combinations; } //递归函数 public void generateAll(char[] current, int position, List result){ //递归出口 if(current.length == position){//如果当前长度达到2*n,则出递归 if(valid(current)){ result.add(new String(current)); } }else{ current[position] = '('; generateAll(current, position+1,result); current[position] = ')'; generateAll(current,position+1,result); } } public boolean valid(char[] current) { int balance = 0; for (char c: current) { if (c == '(') { ++balance; } else { --balance; } if (balance < 0) { return false; } } return balance == 0; } }
方法2:暴力解法改进
方法1在生成长度为2*n的字符串后再判断这个字符串是否合法,显然,过程中生成了很多不合法的字符串
改进:在生成字符串的时候就考虑只允许生成合法的字符串(
若'('的数量小于n,则当前位置可以填‘(’
若')'的数量小于'(',则当前位置可以填’)‘
注意每次填完括号后要把当前位置还原
class Solution { public ListgenerateParenthesis(int n) { List result = new ArrayList (); generateAll(new StringBuilder(),result,0,0,n); return result; } public void generateAll(StringBuilder cur, List result, int left, int right, int pos){ //递归出口 if(cur.length() == pos*2){ result.add(cur.toString()); return; }else { if(left //左括号共n个,如果当前还有左括号剩余 cur.append('('); generateAll(cur,result,left+1,right,pos); cur.deleteCharAt(cur.length()-1);//还原,以备当前位置添加右括号的情况 } if(right < left){ cur.append(')'); generateAll(cur,result,left,right+1,pos); cur.deleteCharAt(cur.length()-1); } } } }