[LeetCode]: 22 : Generate Parentheses

题目:

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:

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

 

思路1:动态规划

分析1~3的括号匹配情况:

1 ()
2 ()(),(())
3 ()()(), (())(), (()()), ()(()), ((()))
我们得出:输入N=插入(n-1) + 包含(n-1)   其中:
插入:是向n-1的结果的左右位置插入()
包含:用()将n-1的每个结果包含起来
 
代码如下:
public ArrayList<String> generateParenthesis( int n )
{
    if ( n == 0 )
    {
        return(null);
    }

    ArrayList<ArrayList<String> > arrTotal = new ArrayList<ArrayList<String> >();

    /* Init */
    ArrayList<String> arrTemp = new ArrayList<String>();
    arrTemp.add( "()" );
    if ( n == 1 )
    {
        return(arrTemp);
    }

    arrTotal.add( arrTemp );

    /* 左右拼接+包含 */
    for ( int i = 1; i < n; i++ )
    {
        ArrayList<String> arrResultTemp = new ArrayList<String>();


        for ( int j = 0; j < arrTotal.get( i - 1 ).size(); j++ )
        {
            /* 包含 */
            String strTemp = "(" + arrTotal.get( i - 1 ).get( j ) + ")";
            if ( !arrResultTemp.contains( strTemp ) )
            {
                arrResultTemp.add( strTemp );
            }

            /* 左拼接 */
            strTemp = "()" + arrTotal.get( i - 1 ).get( j );
            if ( !arrResultTemp.contains( strTemp ) )
            {
                arrResultTemp.add( strTemp );
            }

            /* 右拼接 */
            strTemp = arrTotal.get( i - 1 ).get( j ) + "()";
            if ( !arrResultTemp.contains( strTemp ) )
            {
                arrResultTemp.add( strTemp );
            }
        }

        arrTotal.add( arrResultTemp );
    }

    return(arrTotal.get( n - 1 ) );
}

结果:当n=4的时候结果中遗失了:(()) (()) 这种情况。经分析为:“插入”的时候,应该向n-1子集合众的每个元素 “所有最小为n-2的闭合”区域进行“包含”处理

         貌似思路不对。

改进,还是采用动态规划思想,当根据n-1的所有集合生成n的集合的时候

先把一个(放在每个n-1对括号组合的开头,然后在每个每一个括号配好对的位置插入一个)

代码如下:

public ArrayList<String> generateParenthesis( int n )
{
    if ( n == 0 )
    {
        return(null);
    }

    ArrayList<ArrayList<String> > arrTotal = new ArrayList<ArrayList<String> >();

    /* Init */
    ArrayList<String> arrTemp = new ArrayList<String>();
    arrTemp.add( "()" );
    if ( n == 1 )
    {
        return(arrTemp);
    }

    arrTotal.add( arrTemp );

    for ( int i = 1; i < n; i++ )
    {
        ArrayList<String> arrResultTemp = new ArrayList<String>();

        for ( int j = 0; j < arrTotal.get( i - 1 ).size(); j++ )
        {
            arrResultTemp.add( "()" + arrTotal.get( i - 1 ).get( j ) ); /* 先添加一个下面循环判断不到的情况 */ 
            //System.out.println("--------------------补充 :" + "()"+arrTotal.get(i-1).get(j) );
            
       String strTemp ="("+arrTotal.get(i-1).get(j); //先添加一个( /* 遍历字符串,直到可以加上一个)使得括号闭合 */ int iFlag = 0; int intCounter = 1; while ( intCounter < strTemp.length() ) { if ( strTemp.substring( intCounter, intCounter + 1 ).equals( "(" ) ) { iFlag++; /* (:加一 */ }else{ iFlag--; /* ):减一 */ if ( iFlag == 0 ) /* 满足条件:前面的括号都是闭合的, 补完) */ { //System.out.println("Enter :" + strTemp.substring(0,intCounter+1) ); */ String strTempResult = strTemp.substring(0,intCounter+1)+")"+strTemp.substring(intCounter+1); //System.out.println("XXXXXXXXXXXXX :" + strTempResult); arrResultTemp.add( strTempResult ); } } intCounter++; } } arrTotal.add( arrResultTemp ); } return(arrTotal.get( n - 1 ) ); }

 

思路2:递归+剪枝

用平衡二叉树的构造方法(盗用了网上的图):

    - 先构造一个根节点(

    - 然后给根节点插入左右孩子,左孩子永远插入(,右孩子永远插入)

    - 递归插入,偶数层中的节点包含正确的解

    - 在递归的时候,去掉本身就是错误的分支

 

代码如下:

    public static ArrayList<String> BuildAllData(int n,String strInput, ArrayList<String> arrResult) {
        if(strInput.length() > n*2){
            return arrResult;
        }

        //Check ( and ) ----------------------------------------------------------------
        int iCounter_L= 0;
        int iCounter_R= 0;
        
        //Check (
        for(int i =0;i<strInput.length();i++){
            if(strInput.substring(i, i+1).equals("(")){
                iCounter_L++;
            }
            if(strInput.substring(i, i+1).equals(")")){
                iCounter_R++;
            }
            
        }  
        if(iCounter_L > n){
            return arrResult;
        } 
        if(iCounter_R > n){
            return arrResult;
        }
        
        //System.out.println("strInput : "+strInput);
        //Check () is close 
        if(iCounter_L == iCounter_R && strInput.length() == n*2 && !arrResult.contains(strInput)){
            arrResult.add(strInput);
            //System.out.println(" is OK !");
        }
        
        arrResult = BuildAllData(n,strInput+"(",arrResult);
        
        if(iCounter_L > iCounter_R){  //当左括号的数目大于有括号的数目的时候 才能够添加右括号
            arrResult = BuildAllData(n,strInput+")",arrResult);
        }
        
        
        return arrResult;
     }
    
    public static ArrayList<String> generateParenthesis(int n) {
        if ( n == 0 )
        {
            return(null);
        }

        ArrayList<String> arrResult = new ArrayList<String>();
        arrResult = BuildAllData(n,"(",arrResult);
        
        return arrResult;
    }

 

posted @ 2015-10-12 22:17  savageclc26  阅读(146)  评论(0编辑  收藏  举报