forked from realpacific/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenerateParentheses.kt
64 lines (54 loc) · 2.02 KB
/
GenerateParentheses.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package questions
import _utils.UseCommentAsDocumentation
import utils.assertIterableSameInAnyOrder
/**
* Given `n` pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
*
* [Source](https://leetcode.com/problems/generate-parentheses/)
*/
@UseCommentAsDocumentation
private fun generateParenthesis(n: Int): List<String> {
if (n == 1) return listOf(VALID_PAREN)
val result = mutableSetOf<String>()
result.add(VALID_PAREN)
_generateParens(n, 0, result)
return result // contains intermediate values from different iterations
.filter { it.length == 2 * n } // remove the intermediate values (these are of length < 2*n)
.toList()
}
private fun _generateParens(n: Int, currentIteration: Int, result: MutableSet<String>) {
if (currentIteration > n) {
return
}
HashSet(result) // clone
.forEach {
result.add(VALID_PAREN + it) // add parens at start
result.add(it + VALID_PAREN) // add parens at end
for (i in 0..it.length / 2) {
val newValue = addPairAfterStartParensAt(it, i) // add parens in the middle
result.add(newValue)
}
}
_generateParens(n, currentIteration + 1, result)
}
private fun addPairAfterStartParensAt(str: String, startIndexOffset: Int): String {
val occurrenceOfStartParen = str.indexOf('(', startIndex = startIndexOffset)
return str.substring(0, occurrenceOfStartParen + 1)
.plus(VALID_PAREN)
.plus(str.substring(occurrenceOfStartParen + 1))
}
private const val VALID_PAREN = "()"
fun main() {
assertIterableSameInAnyOrder(
listOf("((()))", "(()())", "(())()", "()(())", "()()()"),
generateParenthesis(3),
)
assertIterableSameInAnyOrder(
listOf("()()", "(())"),
generateParenthesis(2),
)
assertIterableSameInAnyOrder(
actual = generateParenthesis(1),
expected = listOf("()")
)
}