HF_Cherish

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. Problem

给定n对括号,生成所有可能的括号组合

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:

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

2. Solution

采用树的方式来选择生成所有的组合结果树,每种组合是树的一个遍历分支。

有两种方法,基本一样的。

第一种,定义三个变量:

  • lLeft:表示还没有用的左括号数;
  • rLeft:表示还没有用的右括号数;
  • now:表示当前已用的字符串;

其中lLeft<=rLeft始终成立。则有如下判断:

  • lLeft == 0:左括号用完,加上剩下的右括号,构建一个完整的串;
  • lLeft != 0:
    • 接下来可以加一个左括号(总是可以)
    • 如果lLeft < rLeft,则接下来也可以加一个右括号

代码如下:

 1 public class Solution {
 2     List<String> res;
 3     public void dfs( String now, int lLeft, int rLeft ){
 4         if( lLeft == 0 ){
 5             char[] rLeftString = new char[rLeft];
 6             for( int i=0; i<rLeft; i++ )
 7                 rLeftString[i] = ')';
 8             res.add( now + String.valueOf(rLeftString) );
 9         }
10         else{
11             dfs( now + "(", lLeft-1, rLeft );
12             if( lLeft < rLeft )
13                 dfs( now + ")", lLeft, rLeft-1 );
14         }
15     }
16     
17     public List<String> generateParenthesis( int n ){
18         res = new ArrayList<String>();
19         dfs( "", n, n );
20         return res;
21     }
22 }
View Code

 

第二种,定义三个变量:

  • i:表示已配成对的括号数,初始为0;
  • j:表示当前未配对的左括号,初始为1(如果n>0);
  • next:当前节点的下一个节点值

则有如下判断(以n=3为例,用0代表左括号,1代表右括号):

  • i==3:终止
  • i!=3:
    • i+j == 3,  next=1, i++, j--;  //意味着所有的左括号都已经出现了,但是仍未完成配对
    • i+j != 3  //左括号还没有出现完
      • j>0  //当前还有左括号未配对
        • next=0, j++;
        • next=1, i++, j--;
      • j==0, next=0, j++  //当前的左括号都已配对

下图是n=3时的判断实例,其中最左的一个分支是((())),第二个是(()()):

 

代码如下:

public class Solution {
    List<String> res;
    public void expand( String now, int i, int j, int n ){
        //finish matching
        if( i == n ){
            res.add( now );
            return;
        }
        //all left parentheses are used
        if( i + j == n )
            expand( now + ")", i+1, j-1, n );
        //there're still unused left parentheses
        else{
            //there're still unmatched left parentheses
            if( j > 0 ){
                expand( now + "(", i, j+1, n );
                expand( now + ")", i+1, j-1, n );
            }
            //all used left parentheses are matched at present
            else if( j == 0 )
                expand( now + "(", i, j+1, n );
        }
    }
    
    public List<String> generateParenthesis( int n ){
        res = new ArrayList<String>();
        expand( "(", 0, 1, n );
        return res;
    }
}
View Code

 

posted on 2015-08-10 20:55  HF_Cherish  阅读(158)  评论(0编辑  收藏  举报