The problem
Given n
pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Examples
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Input: n = 1
Output: ["()"]
Constraints
- 1 <= n <= 8
Explanation
Before we jump to the solution, let’s figure out what well-formed parentheses mean.
In this problem, this means when you’re writing the code using nested parentheses, you want them to be nested in a valid way, like (()())
.
We can’t have a right
)
parenthesis come before a left(
parenthesis. In the example section, you can see that for each left parenthesis we have a matching right parenthesis that comes after it at some point. Then = 3
means that we have three pairs. In total, we have six parentheses (three are going to be open(
, and three are going to be closed)
).
Backtracking Solution
func generateParenthesis(_ n: Int) -> [String] {
var stack: [String] = []
var res: [String] = []
func backtrack(_ openN: Int, _ closedN: Int) {
if openN == closedN && closedN == n {
res.append(stack.joined(separator: ""))
return
}
if openN < n {
stack.append("(")
backtrack(openN + 1, closedN)
stack.removeLast()
}
if closedN < openN {
stack.append(")")
backtrack(openN, closedN + 1)
stack.removeLast()
}
}
backtrack(0, 0)
return res
}
Explanation
Let’s say we start with an empty array:
- We know that we can’t start with a closing
)
parenthesis; we can only start with an open(
parenthesis. - We can have another open
(
parenthesis because our limit is3
open parentheses, and so far we have two. - What if we wanted to add a closing
)
parenthesis instead of an open(
? We can do it because at this point we have only one open parenthesis, and zero closed, but when we add a closed parenthesis, the close count also changes to one.
You can see that we keep count of our open and closed parentheses, which helps us add an open parenthesis only when the condition close < open
is satisfied.
When we add a parenthesis, we update our counters.
We can solve this problem by using a backtracking algorithm.
- We will be keeping track of how many open and closed parentheses are left
- And check if the condition
close < open
is satisfied
In the picture, you can see how the algorithm will generate the result, with three of each parenthesis and valid ordering.
Time/ Space complexity
- Time complexity: O(4^n/sqrt(n))
- Space complexity: O(n)