zoukankan      html  css  js  c++  java
  • [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;
        }
  • 相关阅读:
    2018第45周日
    RabbitMQ消息的消费与持久化
    Rabbitmq的调度策略
    Rabbitmq交换器Exchange和消息队列
    RabbitMQ概念
    微服务拆分
    微服务演化
    2018第44周日
    福勒(Martin Fowler)
    微服务架构定义那点事
  • 原文地址:https://www.cnblogs.com/savageclc26/p/4873033.html
Copyright © 2011-2022 走看看