Finding all combinations of well-formed brackets

后端 未结 29 1513
盖世英雄少女心
盖世英雄少女心 2020-11-28 02:34

This came up while talking to a friend and I thought I\'d ask here since it\'s an interesting problem and would like to see other people\'s solutions.

The task is to

相关标签:
29条回答
  • 2020-11-28 02:51

    A simple F#/OCaml solution :

    let total_bracket n =
        let rec aux acc = function
            | 0, 0 -> print_string (acc ^ "\n")
            | 0, n -> aux (acc ^ ")") (0, n-1)
            | n, 0 -> aux (acc ^ "(") (n-1, 1)
            | n, c ->
                    aux (acc ^ "(") (n-1, c+1);
                    aux (acc ^ ")") (n,   c-1)
        in
        aux "" (n, 0)
    

    0 讨论(0)
  • 2020-11-28 02:51

    Another inefficient but elegant answer =>

    public static Set<String> permuteParenthesis1(int num)
    {   
        Set<String> result=new HashSet<String>();
        if(num==0)//base case
            {
                result.add("");
                return result;
            }
        else
            {
                Set<String> temp=permuteParenthesis1(num-1); // storing result from previous result.
                for(String str : temp)
                {
                    for(int i=0;i<str.length();i++)
                    {
                        if(str.charAt(i)=='(')
                        {
                            result.add(insertParen(str, i)); // addinng `()` after every left parenthesis.
                        }
                    }
                    result.add("()"+str); // adding "()" to the beginning.
                }
    
            }
        return result;
    
    
    }
    public static String insertParen(String str,int leftindex)
    {
        String left=str.substring(0, leftindex+1);
        String right=str.substring(leftindex+1);
        return left+"()"+right;
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(permuteParenthesis1(3));
    
    }
    
    0 讨论(0)
  • 2020-11-28 02:51
    void function(int n, string str, int open, int close)
    {
        if(open>n/2 || close>open)
            return;
        if(open==close && open+close == n)
        {
            cout<<" "<<str<<endl;
            return;
        }
        function(n, str+"(", open+1, close);
        function(n, str+")", open, close+1);
    }
    

    Caller - function(2*brackets, str, 0, 0);

    0 讨论(0)
  • 2020-11-28 02:52

    The number of possible combinations is the Catalan number of N pairs C(n).

    This problem was discussed on the joelonsoftware.com forums pretty exentsively including iterative, recursive and iterative/bitshifting solutions. Some pretty cool stuff there.

    Here is a quick recursive solution suggested on the forums in C#:

    C#

    public void Brackets(int pairs) {
        if (pairs > 1) Brackets(pairs - 1);
        char[] output = new char[2 * pairs];
    
        output[0] = '(';
        output[1] = ')';
    
        foo(output, 1, pairs - 1, pairs, pairs);
        Console.writeLine();
    }
    
    public void foo(char[] output, int index, int open, int close,
            int pairs) {
        int i;
    
        if (index == 2 * pairs) {
            for (i = 0; i < 2 * pairs; i++)
                Console.write(output[i]);
            Console.write('\n');
            return;
        }
    
        if (open != 0) {
            output[index] = '(';
            foo(output, index + 1, open - 1, close, pairs);
        }
    
        if ((close != 0) && (pairs - close + 1 <= pairs - open)) {
            output[index] = ')';
            foo(output, index + 1, open, close - 1, pairs);
        }
    
        return;
    }
    

    Brackets(3);

    Output:
    ()
    (()) ()()
    ((())) (()()) (())() ()(()) ()()()

    0 讨论(0)
  • 2020-11-28 02:52

    Here's another F# solution, favoring elegance over efficiency, although memoization would probably lead to a relatively well performing variant.

    let rec parens = function
    | 0 -> [""]
    | n -> [for k in 0 .. n-1 do
            for p1 in parens k do
            for p2 in parens (n-k-1) ->
              sprintf "(%s)%s" p1 p2]
    

    Again, this only yields a list of those strings with exactly n pairs of parens (rather than at most n), but it's easy to wrap it.

    0 讨论(0)
  • 2020-11-28 02:52

    ruby version:

    def foo output, open, close, pairs
      if open == pairs and close == pairs
          p output
      else
        foo(output + '(', open+1, close, pairs) if open < pairs
        foo(output + ')', open, close+1, pairs) if close < open
      end
    end
    foo('', 0, 0, 3)
    
    0 讨论(0)
提交回复
热议问题