Generate Parentheses

Problem statement

Given n pairs, return every string of well-formed parentheses. Order in the list does not matter.

Example:

Input:

n = 3

Expected output:

["((()))", "(()())", "(())()", "()(())", "()()()"]

Well-formed means two things: you never have more ) than ( in any prefix, and you finish with the same count of each.

Practice on LeetCode: Generate Parentheses

What we are growing

The string is built one character at a time. At every step you hold a prefix, plus how many opens and closes you have already used.

n = 2 is small enough to draw:

              ""
              |
              (
            /   \
          ((     ()
          |       |
         (()     ()(
          |       |
        (())     ()()

From "(" you may add ( or ). From "((" you may only add ). From "()" you may only add ( — a second ) would make "())", which is already illegal.

You never start with ). Zero opens, so a close is refused.

Why not generate everything

Each of the 2n positions could be ( or ). That is 2^{2n} strings, then a filter. n = 8 is 65,536 candidates, most of them junk like ")))((((".

You do not need those strings. If a prefix is already invalid, every extension of it is invalid. Backtracking refuses the bad prefix, so the junk is never built.

The number of good strings is the Catalan number C_n. The algorithm’s job is to grow only valid prefixes until the length hits 2n.

Golang Solution

A nested generate closes over result. Add ( while leftCount < n. Add ) only while rightCount < leftCount. When len(current) == 2*n, both counters are n, so neither branch fires again — the extra return you might expect is unnecessary.

Time: O(C_n · n)C_n results, each of length 2n
Space: O(n) — recursion depth, plus the output list

func generateParenthesis(n int) []string {

    var result []string

    var generate func(current string, leftCount, rightCount int)

    generate = func(current string, leftCount, rightCount int) {
        if len(current) == 2*n {
            result = append(result, current)
        }

        if leftCount < n {
            generate(current+"(", leftCount+1, rightCount)
        }
        if rightCount < leftCount {
            generate(current+")", leftCount, rightCount+1)
        }
    }
    generate("", 0, 0)

    return result
}

current+"(" allocates a new string each call. That is fine at interview n (up to 8). A []byte you append and backtrack is the same idea with less copying.