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 Rust DSA
implementation can be compared directly with the rest of the DSA track.
Basic Implementation
basic.rs
use std::collections::HashMap;
fn main() {
let arr = [3, 5, 2, 5, 3, 8, 2];
let mut count: HashMap<i32, i32> = HashMap::new();
for value in arr {
*count.entry(value).or_insert(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
- The checked source imports
std::collections::HashMapand useslet mut count: HashMap<i32, i32> = HashMap::new(); there is no string orchariteration in this Rust lesson. - The input is the fixed integer array
[3, 5, 2, 5, 3, 8, 2]. Because the elements arei32copies,for value in arrcopies each value into the loop. - Counting uses
*count.entry(value).or_insert(0) += 1.entryowns the copied key,or_insert(0)creates missing counts, and the dereference mutates the storedi32count in place. - The trace records counts growing through
{3: 1},{3: 1, 5: 1},{3: 1, 5: 1, 2: 1}, then updating repeats to the final{3: 2, 5: 2, 2: 2, 8: 1}. - The second pass also iterates over
arr, so first-non-repeating order comes from the original array, not from hash-map iteration order. - Lookup uses indexing syntax
count[&value], borrowing the copied loop value as the key. NoOptionsentinel is exposed here; the first pass has inserted every value before the scan. - The scan skips indices
0through4with frequency2, finds8at index5, prints it withprintln!("{}", value), and breaks before the final2. - The trace exposes count-table states only; it does not show bucket placement or collision 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.