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 Go DSA
implementation can be compared directly with the rest of the DSA track.
Basic Implementation
basic.go
package main
import "fmt"
func main() {
arr := []int{3, 5, 2, 5, 3, 8, 2}
count := map[int]int{}
for _, value := range arr {
count[value]++
}
for _, value := range arr {
if count[value] == 1 {
fmt.Println(value)
break
}
}
}
Complexity
- Time: O(n) average
- Space: O(k) for k distinct values
Implementation notes
- Go stores the input as
arr := []int{3, 5, 2, 5, 3, 8, 2}and counts withcount := map[int]int{}; there is no byte, rune, or string iteration in this checked source. - The first
for _, value := range arrcopies eachintintovalueand usescount[value]++. A missing key reads as theintzero value, so the first increment creates a count of1. - The trace records the count table growing through
{3: 1},{3: 1, 5: 1},{3: 1, 5: 1, 2: 1}, then updating repeated values to the final{3: 2, 5: 2, 2: 2, 8: 1}. - The second pass ranges over
arragain, not over the map, so the scan order is deterministic despite Go's unspecified map iteration order. - That scan skips indices
0through4because values3,5, and2have frequency2; at index5,count[8] == 1, sofmt.Println(value)prints8andbreakstops before the final2. - Go's map may resize internally and handles hashing/collisions behind the runtime API, but this source and trace expose only key lookup and count mutation, not bucket-level behavior.
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.