Finding all combinations of well-formed brackets

后端 未结 29 1505
盖世英雄少女心
盖世英雄少女心 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 03:12

    F#:

    Here is a solution that, unlike my previous solution, I believe may be correct. Also, it is more efficient.

    #light
    
    let brackets2 n =
        let result = new System.Collections.Generic.List<_>()
        let a = Array.create (n*2) '_'
        let rec helper l r diff i =
            if l=0 && r=0 then
                result.Add(new string(a))
            else
                if l > 0 then
                    a.[i] <- '('
                    helper (l-1) r (diff+1) (i+1)
                if diff > 0 then
                    a.[i] <- ')'
                    helper l (r-1) (diff-1) (i+1)
        helper n n 0 0
        result
    

    Example:

    (brackets2 4) |> Seq.iter (printfn "%s")
    
    (*
    (((())))
    ((()()))
    ((())())
    ((()))()
    (()(()))
    (()()())
    (()())()
    (())(())
    (())()()
    ()((()))
    ()(()())
    ()(())()
    ()()(())
    ()()()()
    *)
    
    0 讨论(0)
  • 2020-11-28 03:13

    An attempt with memoization:

    void push_strings(int i, int j ,vector<vector <string>> &T){
        for (int k=0; k< T[j].size(); ++k){
            for (int l=0; l< T[i - 1 - j].size(); ++l){
                string s = "(" + T[j][k] + ")" + T[i-1 - j][l];
                T[i].push_back(s);
            }
        }
    }
    
    vector<string> generateParenthesis(int n) {
        vector<vector <string>> T(n+10);
        T[0] = {""};
    
        for (int i =1; i <=n; ++i){
            for(int j=0; j<i; ++j){
                push_strings(i,j, T);
            }
        }
    
        return T[n];
    }
    
    0 讨论(0)
  • 2020-11-28 03:15

    Haskell:

    I tried to come up with an elegant list monad-y way to this:

    import Control.Applicative
    
    brackets :: Int -> [String]
    brackets n = f 0 0 where
        f pos depth =
            if pos < 2*n
                then open <|> close
                else stop where
                    -- Add an open bracket if we can
                    open =
                        if depth < 2*n - pos
                            then ('(' :) <$> f (pos+1) (depth+1)
                            else empty
    
                    -- Add a closing bracket if we can
                    close = 
                        if depth > 0
                            then (')' :) <$> f (pos+1) (depth-1)
                            else empty
    
                    -- Stop adding text.  We have 2*n characters now.
                    stop = pure ""
    
    main = readLn >>= putStr . unlines . brackets
    
    0 讨论(0)
  • 2020-11-28 03:18

    Damn - everyone beat me to it, but I have a nice working example :)

    http://www.fiveminuteargument.com/so-727707

    The key is identifying the rules, which are actually quite simple:

    • Build the string char-by-char
    • At a given point in the string
      • if brackets in string so far balance (includes empty str), add an open bracket and recurse
      • if all open brackets have been used, add a close bracket and recurse
      • otherwise, recurse twice, once for each type of bracket
    • Stop when you get to the end :-)
    0 讨论(0)
  • 2020-11-28 03:18
      validParentheses: function validParentheses(n) {
        if(n === 1) {
          return ['()'];
        }
        var prevParentheses = validParentheses(n-1);
        var list = {};
        prevParentheses.forEach(function(item) {
          list['(' + item + ')'] = null;
          list['()' + item] = null;
          list[item + '()'] = null;
        });
        return Object.keys(list);
      }
    
    0 讨论(0)
提交回复
热议问题