Skip to content

Commit

Permalink
Generate Parentheses
Browse files Browse the repository at this point in the history
  • Loading branch information
dksifoua committed Jul 14, 2024
1 parent d7fde34 commit 066b9fa
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
| 0002 | Medium | Add Two numbers | LinkedList, Recursion | |
| 0011 | Medium | Container With Most Water | Array, Two Pointers, Greedy | [solution](./docs/0011-Container-With-Most-Water.md) |
| 0015 | Medium | Three sum | Array, Two Pointers, Sorting | [solution](./docs/0015-Three-Sum.md) |
| 0022 | Medium | Generate Parentheses | String, Dynamic Programming, Backtracking | [solution](./docs/0022-Generate-Parentheses.md) |
| 0036 | Medium | Valid Sudoku | Array, HashTable, Matrix | [solution](./docs/0036-Valid-Sudoku.md) |
| 0042 | Hard | Trapping Rain Water | Array, Two Pointers, Dynamic Programming, Stack | [solution](./docs/0042-Trapping-Rain-Water.md) |
| 0049 | Medium | Group Anagrams | Array, HashTable, String, Sorting | [solution](./docs/0049-Group-Anagrams.md ) |
Expand Down
34 changes: 34 additions & 0 deletions docs/0022-Generate-Parentheses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# [Generate Parentheses](https://leetcode.com/problems/generate-parentheses/description/)

## Intuition

Generating all combinations of well-formed parentheses involves understanding the balance between open and close
parentheses. A well-formed parentheses sequence must ensure that at no point do the close parentheses exceed the open
ones, and by the end, the counts of open and close parentheses must be equal. This ensures that every opening
parenthesis has a corresponding closing one, forming valid sequences.

## Approach

The approach to solving this problem is to use backtracking. Backtracking allows us to explore all possible combinations
of parentheses and ensures we only consider valid sequences. Here’s a step-by-step breakdown:

1. **Initialization:** We start with an empty string and zero counts for both open and close parentheses.
2. **Backtracking Function:** The backtrack function recursively builds the parentheses sequences.
- *Base Case:* When the counts of both open and close parentheses reach `N`, a valid sequence is formed, and we add
it to the result list.
- *Add Open Parenthesis:* If the count of open parentheses is less than `N`, we can add an open parenthesis and
recursively call the function.
- *Add Close Parenthesis:* If the count of close parentheses is less than the count of open parentheses, we can add
a close parenthesis and recursively call the function.
3. **Recursion:** This process continues until all valid sequences are generated and stored in the result list.

## Complexity

- **Time Complexity:** The time complexity is `O(4^N / \sqrt{N})`. This is derived from the fact that the number of
valid sequences is given by the [nth Catalan number](https://en.wikipedia.org/wiki/Catalan_number), which grows exponentially.
- **Space Complexity:** The space complexity is `O(4^N / \sqrt{N})` for the result list storing all sequences.
Additionally, the recursion stack depth is `O(N)`, making the auxiliary space complexity also `O(N)`.

## Code

- [Java](../src/main/java/io/dksifoua/leetcode/generateparentheses/Solution.java)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.dksifoua.leetcode.generateparentheses;

import java.util.ArrayList;
import java.util.List;

public class Solution {

private void backtrack(List<String> result, String current, int openedParenthesis, int closedParenthesis, int n) {
if (openedParenthesis == n && closedParenthesis == n) {
result.add(current);
return;
}

if (openedParenthesis < n) {
backtrack(result, current + "(", openedParenthesis + 1, closedParenthesis, n);
}

if (closedParenthesis < openedParenthesis) {
backtrack(result, current + ")", openedParenthesis, closedParenthesis + 1, n);
}
}

public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>();
backtrack(result, "", 0, 0, n);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.dksifoua.leetcode.generateparentheses;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

public class SolutionTest {

private final Solution solution = new Solution();

@Test
void test1() {
List<String> expected = Arrays.asList("((()))", "(()())", "(())()", "()(())", "()()()");
List<String> actual = solution.generateParenthesis(3);
for (String elt: actual) {
Assertions.assertTrue(expected.contains(elt));
}
}

@Test
void test2() {
List<String> expected = List.of("()");
List<String> actual = solution.generateParenthesis(1);
for (String elt: actual) {
Assertions.assertTrue(expected.contains(elt));
}
}
}

0 comments on commit 066b9fa

Please sign in to comment.