Every Well-Formed Bracket Sequence of a Given Length
Solve this Problemn, produce every string of length 2n made of n opening and n closing brackets that is well-formed — every prefix has at least as many opens as closes, and the whole string balances out to zero by the end.
Trying every character independently at every position and checking validity only once a string is complete works, but wastes enormous effort on prefixes that were already unrecoverable — a string beginning with a closing bracket is built out to full length before that fact is even noticed. Tracking how many opens and closes have been placed so far, and only ever allowing a placement that keeps the running balance non-negative, means every partial string the search ever holds is one that could still become valid — nothing hopeless is ever built in the first place.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
0 ≤ n ≤ 8 - ◆
Every returned string has exactly n opening and n closing brackets - ◆
Results are returned sorted in ascending (lexicographic) order for a stable, checkable answer
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Try Every Character at Every Position, Validate at the End
BruteBuild every possible string of length 2n by trying both '(' and ')' independently at each position — no rule about validity is applied during construction at all. Only once a full-length string exists does a separate scan check whether it's ever balanced correctly. This finds every valid sequence eventually, but it also fully constructs and checks strings that were doomed from their very first character — a string starting with ')' can never become valid, yet every one of its 2^(2n-1) completions still gets built and rejected one at a time.
O(2²ⁿ · n)O(2²ⁿ · n)1class Solution {
2 public String[] wellFormedBracketSequences(int n) {
3 List<String> result = new ArrayList<>();
4 char[] current = new char[2 * n];
5 generateAll(current, 0, result);
6 return result.toArray(new String[0]);
7 }
8
9 private void generateAll(char[] current, int pos, List<String> result) {
10 if (pos == current.length) {
11 if (isValid(current)) {
12 result.add(new String(current));
13 }
14 return;
15 }
16 current[pos] = '(';
17 generateAll(current, pos + 1, result);
18 current[pos] = ')';
19 generateAll(current, pos + 1, result);
20 }
21
22 private boolean isValid(char[] s) {
23 int balance = 0;
24 for (char c : s) {
25 balance += (c == '(') ? 1 : -1;
26 if (balance < 0) return false;
27 }
28 return balance == 0;
29 }
30}Optimal — Only Place a Bracket That Keeps the Prefix Valid
OptimalBuild the string one character at a time, but only ever place a character that can't already doom the result: '(' is allowed as long as fewer than n have been placed so far, and ')' is allowed only when fewer closes than opens have been placed (so the prefix never goes negative). Every branch this ever explores is therefore a valid prefix of some eventual answer — nothing equivalent to "starts with an unmatched )" is ever constructed, let alone fully built out and then discarded.
O(4ⁿ / √n)O(n)1class Solution {
2 public String[] wellFormedBracketSequences(int n) {
3 List<String> result = new ArrayList<>();
4 char[] path = new char[2 * n];
5 backtrack(path, 0, 0, 0, n, result);
6 return result.toArray(new String[0]);
7 }
8
9 private void backtrack(char[] path, int pos, int openCount, int closeCount, int n, List<String> result) {
10 if (pos == 2 * n) {
11 result.add(new String(path));
12 return;
13 }
14 if (openCount < n) {
15 path[pos] = '(';
16 backtrack(path, pos + 1, openCount + 1, closeCount, n, result);
17 }
18 if (closeCount < openCount) {
19 path[pos] = ')';
20 backtrack(path, pos + 1, openCount, closeCount + 1, n, result);
21 }
22 }
23}