Hash Tables
First Non-Repeating Value
Find the first input value whose final frequency is one.
Algorithm
Canonical input [3, 5, 2, 5, 3, 8, 2] prints 8.
The replay uses the same input in every language, so this Kotlin DSA
implementation can be compared directly with the rest of the DSA track.
Basic Implementation
basic.kt
fun main() {
val arr = listOf(3, 5, 2, 5, 3, 8, 2)
val count = mutableMapOf<Int, Int>()
for (value in arr) {
count[value] = count.getOrDefault(value, 0) + 1
}
for (value in arr) {
if (count[value] == 1) {
println(value)
break
}
}
}
Complexity
- Time: O(n) average
- Space: O(k) for k distinct values
Implementation notes
- Kotlin stores the input as
val arr = listOf(3, 5, 2, 5, 3, 8, 2), a read-onlyList<Int>reference; the list is scanned twice and not mutated. - The frequency table is
val count = mutableMapOf<Int, Int>(). The binding is stable, but the map contents mutate during the first pass. - Count updates use
count[value] = count.getOrDefault(value, 0) + 1, so a missingIntkey reads as zero before the first write. - The second pass uses the original
arrorder, not map iteration order, so the first non-repeating result does not depend on hash bucket ordering. count[value] == 1compares the nullable map lookup result with1; for these values every key was inserted by the first pass before the lookup.- The trace records count states from
{}through{3: 2, 5: 2, 2: 2, 8: 1}, then scans values3,5,2,5,3as repeated before finding8. - On the first frequency-one value,
println(value)prints8andbreakstops the scan.
two-pass lookup
The first pass builds a frequency table. The second pass keeps the original order and stops at the first value with frequency one.