Skip to content

Commit 3a43932

Browse files
authored
Merge pull request ByteByteGoHq#12 from marttp/kotlin-hashmap-set
Kotlin chapter 2 - Hash Maps and Sets
2 parents 200dfd8 + d7fa10e commit 3a43932

8 files changed

+218
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
fun geometricSequenceTriplets(nums: List<Int>, r: Int): Int {
2+
// leftMap and rightMap will use 'getOrDefault' to ensure the default value of 0 is returned when
3+
// accessing a key that doesn’t exist in the hash map. This effectively sets
4+
// the default frequency of all elements to 0.
5+
val leftMap = mutableMapOf<Int, Int>()
6+
val rightMap = mutableMapOf<Int, Int>()
7+
var count = 0
8+
// Populate 'rightMap' with the frequency of each element in the array.
9+
for (x in nums) {
10+
rightMap[x] = rightMap.getOrDefault(x, 0) + 1
11+
}
12+
// Search for geometric triplets that have x as the center.
13+
for (x in nums) {
14+
// Decrement the frequency of x in 'rightMap' since x is now being
15+
// processed and is no longer to the right.
16+
rightMap[x] = rightMap.getOrDefault(x, 0) - 1
17+
if (x % r == 0) {
18+
count += leftMap.getOrDefault(x / r, 0) * rightMap.getOrDefault(x * r, 0)
19+
}
20+
// Increment the frequency of x in 'leftMap' since it'll be a part of the
21+
// left side of the array once we iterate to the next value of x.
22+
leftMap[x] = leftMap.getOrDefault(x, 0) + 1
23+
}
24+
return count
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fun longestChainOfConsecutiveNumbers(nums: List<Int>): Int {
2+
if (nums.isEmpty()) {
3+
return 0
4+
}
5+
val numSet = nums.toSet()
6+
var longestChain = 0
7+
for (num in numSet) {
8+
// If the current number is the smallest number in its chain, search for
9+
// the length of its chain.
10+
if (num - 1 !in numSet) {
11+
var currentNum = num
12+
var currentChain = 1
13+
// Continue to find the next consecutive numbers in the chain.
14+
while (currentNum + 1 in numSet) {
15+
currentNum++
16+
currentChain++
17+
}
18+
longestChain = maxOf(longestChain, currentChain)
19+
}
20+
}
21+
return longestChain
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fun longestChainOfConsecutiveNumbersBruteForce(nums: List<Int>): Int {
2+
if (nums.isEmpty()) {
3+
return 0
4+
}
5+
var longestChain = 0
6+
// Look for chains of consecutive numbers that start from each number.
7+
for (num in nums) {
8+
var currentNum = num
9+
var currentChain = 1
10+
// Continue to find the next consecutive numbers in the chain.
11+
while (currentNum + 1 in nums) {
12+
currentNum++
13+
currentChain++
14+
}
15+
longestChain = maxOf(longestChain, currentChain)
16+
}
17+
return longestChain
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fun pairSumUnsortedTwoPass(nums: List<Int>, target: Int): List<Int> {
2+
val numMap = mutableMapOf<Int, Int>()
3+
// First pass: Populate the hash map with each number and its
4+
// index.
5+
for ((i, num) in nums.withIndex()) {
6+
numMap[num] = i
7+
}
8+
// Second pass: Check for each number's complement in the hash map.
9+
for ((i, num) in nums.withIndex()) {
10+
val complement = target - num
11+
if (complement in numMap && numMap[complement] != i) {
12+
return listOf(i, numMap[complement]!!)
13+
}
14+
}
15+
return emptyList()
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fun pairSumUnsorted(nums: List<Int>, target: Int): List<Int> {
2+
val hashmap = mutableMapOf<Int, Int>()
3+
for ((i, x) in nums.withIndex()) {
4+
if (target - x in hashmap) {
5+
return listOf(hashmap[target - x]!!, i)
6+
}
7+
hashmap[x] = i
8+
}
9+
return emptyList()
10+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
fun verifySudokuBoard(board: List<List<Int>>): Boolean {
2+
// Create hash sets for each row, column, and subgrid to keep
3+
// track of numbers previously seen on any given row, column, or
4+
// subgrid.
5+
val rowSets: List<HashSet<Int>> = List(9) {
6+
hashSetOf()
7+
}
8+
val colSets: List<HashSet<Int>> = List(9) {
9+
hashSetOf()
10+
}
11+
val subgridSets: List<List<HashSet<Int>>> = List(3) {
12+
List(3) {
13+
hashSetOf()
14+
}
15+
}
16+
for (r in 0 until 9) {
17+
for (c in 0 until 9) {
18+
val num = board[r][c]
19+
if (num == 0) {
20+
continue
21+
}
22+
// Check if 'num' has been seen in the current row,
23+
// column, or subgrid.
24+
if (rowSets[r].contains(num)) {
25+
return false
26+
}
27+
if (colSets[c].contains(num)) {
28+
return false
29+
}
30+
if (subgridSets[r / 3][c / 3].contains(num)) {
31+
return false
32+
}
33+
// If we passed the above checks, mark this value as seen
34+
// by adding it to its corresponding hash sets.
35+
rowSets[r].add(num)
36+
colSets[c].add(num)
37+
subgridSets[r / 3][c / 3].add(num)
38+
}
39+
}
40+
return true
41+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
fun zeroStriping(matrix: MutableList<MutableList<Int>>) {
2+
if (matrix.isEmpty() || matrix[0].isEmpty()) {
3+
return
4+
}
5+
val m = matrix.size
6+
val n = matrix[0].size
7+
// Check if the first row initially contains a zero.
8+
var firstRowHasZero = false
9+
for (c in 0 until n) {
10+
if (matrix[0][c] == 0) {
11+
firstRowHasZero = true
12+
break
13+
}
14+
}
15+
// Check if the first column initially contains a zero.
16+
var firstColHasZero = false
17+
for (r in 0 until m) {
18+
if (matrix[r][0] == 0) {
19+
firstColHasZero = true
20+
break
21+
}
22+
}
23+
// Use the first row and column as markers. If an element in the
24+
// submatrix is zero, mark its corresponding row and column in the
25+
// first row and column as 0.
26+
for (r in 1 until m) {
27+
for (c in 1 until n) {
28+
if (matrix[r][c] == 0) {
29+
matrix[0][c] = 0
30+
matrix[r][0] = 0
31+
}
32+
}
33+
}
34+
// Update the submatrix using the markers in the first row and
35+
// column.
36+
for (r in 1 until m) {
37+
for (c in 1 until n) {
38+
if (matrix[0][c] == 0 || matrix[r][0] == 0) {
39+
matrix[r][c] = 0
40+
}
41+
}
42+
}
43+
// If the first row had a zero initially, set all elements in the
44+
// first row to zero.
45+
if (firstRowHasZero) {
46+
for (c in 0 until n) {
47+
matrix[0][c] = 0
48+
}
49+
}
50+
// If the first column had a zero initially, set all elements in
51+
// the first column to zero.
52+
if (firstColHasZero) {
53+
for (r in 0 until m) {
54+
matrix[r][0] = 0
55+
}
56+
}
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
fun zeroStripingHashSets(matrix: MutableList<MutableList<Int>>) {
2+
if (matrix.isEmpty() || matrix[0].isEmpty()) {
3+
return
4+
}
5+
val m = matrix.size
6+
val n = matrix[0].size
7+
val zeroRows = hashSetOf<Int>()
8+
val zeroCols = hashSetOf<Int>()
9+
// Pass 1: Traverse through the matrix to identify the rows and
10+
// columns containing zeros and store their indexes in the
11+
// appropriate hash sets.
12+
for (r in 0 until m) {
13+
for (c in 0 until n) {
14+
if (matrix[r][c] == 0) {
15+
zeroRows.add(r)
16+
zeroCols.add(c)
17+
}
18+
}
19+
}
20+
// Pass 2: Set any cell in the matrix to zero if its row index is
21+
// in 'zero_rows' or its column index is in 'zero_cols'.
22+
for (r in 0 until m) {
23+
for (c in 0 until n) {
24+
if (r in zeroRows || c in zeroCols) {
25+
matrix[r][c] = 0
26+
}
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)