Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a152000

Browse files
committed
Kotlin - Chapter 14: Backtracking
* Combinations of Sum K * Find All Permutations * Find All Subsets * N Queens * Phone Keypad Combinations
1 parent 795c6b1 commit a152000

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
fun combinationsOfSumK(nums: List<Int>, target: Int): List<List<Int>> {
2+
val res = mutableListOf<List<Int>>()
3+
dfs(mutableListOf(), 0, nums, target, res)
4+
return res
5+
}
6+
7+
fun dfs(
8+
combination: MutableList<Int>,
9+
startIndex: Int,
10+
nums: List<Int>,
11+
target: Int,
12+
res: MutableList<List<Int>>
13+
) {
14+
// Termination condition: If the target is equal to 0, we found a combination
15+
// that sums to 'k'.
16+
if (target == 0) {
17+
res.add(ArrayList(combination))
18+
return
19+
}
20+
// Termination condition: If the target is less than 0, no more valid
21+
// combinations can be created by adding it to the current combination.
22+
if (target < 0) {
23+
return
24+
}
25+
// Starting from start_index, explore all combinations after adding nums[i].
26+
for (i in startIndex until nums.size) {
27+
// Add the current number to create a new combination.
28+
combination.add(nums[i])
29+
// Recursively explore all paths that branch from this new combination.
30+
dfs(combination, i, nums, target - nums[i], res)
31+
// Backtrack by removing the number we just added.
32+
combination.removeAt(combination.size - 1)
33+
}
34+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
fun findAllPermutations(nums: List<Int>): List<List<Int>> {
2+
val res = mutableListOf<List<Int>>()
3+
backtrack(nums, mutableListOf(), mutableSetOf(), res)
4+
return res
5+
}
6+
7+
fun backtrack(
8+
nums: List<Int>,
9+
candidate: MutableList<Int>,
10+
used: MutableSet<Int>,
11+
res: MutableList<List<Int>>
12+
) {
13+
// If the current candidate is a complete permutation, add it to the
14+
// result.
15+
if (candidate.size == nums.size) {
16+
res.add(candidate.toList())
17+
return
18+
}
19+
for (num in nums) {
20+
if (num !in used) {
21+
// Add 'num' to the current permutation and mark it as used.
22+
candidate.add(num)
23+
used.add(num)
24+
// Recursively explore all branches using the updated
25+
// permutation candidate.
26+
backtrack(nums, candidate, used, res)
27+
// Backtrack by reversing the changes made.
28+
candidate.removeAt(candidate.size - 1)
29+
used.remove(num)
30+
}
31+
}
32+
}

kotlin/Backtracking/FindAllSubsets.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fun findAllSubsets(nums: List<Int>): List<List<Int>> {
2+
val res = mutableListOf<List<Int>>()
3+
backtrack(0, mutableListOf(), nums, res)
4+
return res
5+
}
6+
7+
fun backtrack(i: Int, currSubset: MutableList<Int>, nums: List<Int>, res: MutableList<List<Int>>) {
8+
// Base case: if all elements have been considered, add the
9+
// current subset to the output.
10+
if (i == nums.size) {
11+
res.add(currSubset.toList())
12+
return
13+
}
14+
// Include the current element and recursively explore all paths
15+
// that branch from this subset.
16+
currSubset.add(nums[i])
17+
backtrack(i + 1, currSubset, nums, res)
18+
// Exclude the current element and recursively explore all paths
19+
// that branch from this subset.
20+
currSubset.removeAt(currSubset.size - 1)
21+
backtrack(i + 1, currSubset, nums, res)
22+
}

kotlin/Backtracking/NQueens.kt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
fun nQueens(n: Int): Int {
2+
// In Kotlin, Global variable is anti-pattern
3+
var res = mutableListOf<Int>()
4+
dfs(0, mutableSetOf(), mutableSetOf(), mutableSetOf(), n, res)
5+
return res[0]
6+
}
7+
8+
fun dfs(
9+
r: Int,
10+
diagonalsSet: MutableSet<Int>,
11+
antiDiagonalsSet: MutableSet<Int>,
12+
colsSet: MutableSet<Int>,
13+
n: Int,
14+
res: MutableList<Int>
15+
) {
16+
// Termination condition: If we have reached the end of the rows,
17+
// we've placed all 'n' queens.
18+
if (r == n) {
19+
res[0] = res[0] + 1
20+
return
21+
}
22+
for (c in 0 until n) {
23+
val currDiagonal = r - c
24+
val currAntiDiagonal = r + c
25+
// If there are queens on the current column, diagonal or
26+
// anti−diagonal, skip this square.
27+
if (c in colsSet || currDiagonal in diagonalsSet || currAntiDiagonal in antiDiagonalsSet) {
28+
continue
29+
}
30+
// Place the queen by marking the current column, diagonal, and
31+
// anti −diagonal as occupied.
32+
colsSet.add(c)
33+
diagonalsSet.add(currDiagonal)
34+
antiDiagonalsSet.add(currAntiDiagonal)
35+
// Recursively move to the next row to continue placing queens.
36+
dfs(r + 1, diagonalsSet, antiDiagonalsSet, colsSet, n, res)
37+
// Backtrack by removing the current column, diagonal, and
38+
// anti −diagonal from the hash sets.
39+
colsSet.remove(c)
40+
diagonalsSet.remove(currDiagonal)
41+
antiDiagonalsSet.remove(currAntiDiagonal)
42+
}
43+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
fun phoneKeypadCombinations(digits: String): List<String> {
2+
val keypadMap = mapOf(
3+
'2' to "abc",
4+
'3' to "def",
5+
'4' to "ghi",
6+
'5' to "jkl",
7+
'6' to "mno",
8+
'7' to "pqrs",
9+
'8' to "tuv",
10+
'9' to "wxyz"
11+
)
12+
val res = mutableListOf<String>()
13+
backtrack(0, mutableListOf(), digits, keypadMap, res)
14+
return res
15+
}
16+
17+
fun backtrack(
18+
i: Int,
19+
currCombination: MutableList<Char>,
20+
digits: String,
21+
keypadMap: Map<Char, String>,
22+
res: MutableList<String>
23+
) {
24+
// Termination condition: if all digits have been considered, add the
25+
// current combination to the output list.
26+
if (currCombination.size == digits.length) {
27+
res.add(currCombination.joinToString(""))
28+
return
29+
}
30+
for (letter in keypadMap[digits[i]]!!) {
31+
// Add the current letter.
32+
currCombination.add(letter)
33+
// Recursively explore all paths that branch from this combination.
34+
backtrack(i + 1, currCombination, digits, keypadMap, res)
35+
// Backtrack by removing the letter we just added.
36+
currCombination.removeAt(currCombination.size - 1)
37+
}
38+
}
39+

0 commit comments

Comments
 (0)