Frequency Counter Pattern Using Hash Map in DSA Rust - Time & Space Complexity
We want to understand how fast we can count how many times each item appears in a list using a hash map.
How does the time needed grow as the list gets bigger?
Analyze the time complexity of the following code snippet.
use std::collections::HashMap;
fn frequency_counter(arr: &[i32]) -> HashMap {
let mut freq = HashMap::new();
for &num in arr {
*freq.entry(num).or_insert(0) += 1;
}
freq
}
This code counts how many times each number appears in the input list and stores the counts in a hash map.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each element in the input array once.
- How many times: Exactly once for each element, so n times if the array has n elements.
- Hash map operations: Each insertion or update is done in average constant time.
As the list gets bigger, the number of steps grows roughly the same as the number of items.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 insert or update steps |
| 100 | About 100 insert or update steps |
| 1000 | About 1000 insert or update steps |
Pattern observation: The work grows in a straight line with the input size.
Time Complexity: O(n)
This means the time needed grows directly in proportion to the number of items in the list.
[X] Wrong: "Using a hash map makes this operation slower because of extra work inside the map."
[OK] Correct: Hash maps let us find and update counts very quickly on average, so the overall time stays proportional to the list size.
Knowing how to count frequencies efficiently is a key skill. It shows you can use the right tools to handle data quickly and is often a building block for more complex problems.
"What if we used a sorted array instead of a hash map to count frequencies? How would the time complexity change?"
Practice
Solution
Step 1: Understand the role of a hash map
A hash map stores key-value pairs, allowing quick lookup of counts for each item.Step 2: Connect to frequency counting
Using the hash map, we track how many times each item appears by updating counts.Final Answer:
To count how many times each item appears in a collection -> Option CQuick Check:
Frequency counting = Counting items [OK]
- Thinking hash map sorts items
- Confusing frequency counting with removing duplicates
- Assuming hash map reverses order
Solution
Step 1: Identify the correct data structure for frequency counting
Frequency counting requires a hash map to store keys and counts.Step 2: Check Rust syntax for hash map initialization
In Rust, HashMap::new() creates an empty hash map; mut allows modification.Final Answer:
let mut freq = HashMap::new(); -> Option DQuick Check:
HashMap::new() initializes empty map [OK]
- Using Vec or HashSet instead of HashMap
- Forgetting mut keyword to modify map
- Confusing capacity with initialization
use std::collections::HashMap;
fn main() {
let items = vec!["apple", "banana", "apple", "orange", "banana", "apple"];
let mut freq = HashMap::new();
for item in items {
let count = freq.entry(item).or_insert(0);
*count += 1;
}
println!("{:?}", freq);
}Solution
Step 1: Count occurrences of each fruit
"apple" appears 3 times, "banana" 2 times, "orange" 1 time in the vector.Step 2: Check how counts are updated in the hash map
Each item increments its count correctly using entry and or_insert.Final Answer:
{"apple": 3, "banana": 2, "orange": 1} -> Option BQuick Check:
Count each fruit correctly = {"apple":3,"banana":2,"orange":1} [OK]
- Assuming counts start at 1 instead of 0
- Forgetting to dereference count to increment
- Confusing output format or order
use std::collections::HashMap;
fn main() {
let items = vec!["cat", "dog", "cat"];
let mut freq = HashMap::new();
for item in items {
let count = freq.entry(item).or_insert(1);
*count += 1;
}
println!("{:?}", freq);
}Solution
Step 1: Understand or_insert initial value
or_insert(1) sets initial count to 1, but counting starts from zero.Step 2: Effect of starting at 1 on counts
Starting at 1 causes counts to be off by one; correct is or_insert(0).Final Answer:
or_insert should start with 0, not 1 -> Option AQuick Check:
Frequency count starts at zero [OK]
- Starting count at 1 inflates frequencies
- Forgetting mut on freq (not error here)
- Misunderstanding dereference necessity
Solution
Step 1: Use hash map to count all word frequencies
Traverse the list, increment counts for each word in the hash map.Step 2: Filter keys with frequency exactly two
Iterate over the hash map entries and collect words with count == 2.Final Answer:
Count frequencies with a hash map, then collect keys with value 2 into a vector -> Option AQuick Check:
Frequency count + filter for 2 = correct approach [OK]
- Sorting does not guarantee frequency counts
- Hash set cannot count duplicates
- Ignoring words with frequency > 1 loses needed data
Ready to prove it?
Pass the test and this pattern moves unknown
