Frequency Counter Pattern Using Hash Map in DSA C++ - Time & Space Complexity
We want to understand how fast the frequency counter pattern runs when counting items.
How does the time needed grow as the list gets bigger?
Analyze the time complexity of the following code snippet.
#include <iostream>
#include <unordered_map>
#include <vector>
void countFrequency(const std::vector<int>& arr) {
std::unordered_map<int, int> freqMap;
for (int num : arr) {
freqMap[num]++;
}
for (const auto& pair : freqMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
}
This code counts how many times each number appears in the list using a hash map.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through the input list once to count frequencies.
- How many times: Exactly once for each element in the list (n times).
- Secondary operation: Looping through the hash map entries to print results.
- How many times: Once for each unique number (k times, where k ≤ n).
As the list grows, the counting loop runs once per item, so operations grow directly with input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 increments in the map |
| 100 | About 100 increments in the map |
| 1000 | About 1000 increments in the map |
Pattern observation: The number of operations grows linearly with the input size.
Time Complexity: O(n)
This means the time to count frequencies grows in direct proportion to the number of items.
[X] Wrong: "Using a hash map makes this operation slower than just looping."
[OK] Correct: Hash maps give almost instant access, so counting frequencies is still fast and scales well.
Understanding how frequency counting scales helps you solve many real problems efficiently and shows you know how to use hash maps well.
"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 and update of counts.Step 2: Apply to frequency counting
We use the hash map keys as elements and values as their counts to track frequency.Final Answer:
To count how many times each element appears in a collection -> Option DQuick Check:
Frequency Counter = Counting elements [OK]
- Thinking hash map sorts elements
- Confusing frequency counting with removing duplicates
- Using hash map to reverse order
Solution
Step 1: Identify correct container for frequency counting
We need a map from characters to integers to store counts.Step 2: Check syntax correctness
std::unordered_map freq; declares a hash map with char keys and int values.Final Answer:
std::unordered_map freq; -> Option BQuick Check:
unordered_map = frequency map [OK]
- Using map with wrong key-value types
- Using unordered_set which stores only keys
- Using vector which is not a map
std::string s = "aabbcc";
std::unordered_map freq;
for (char c : s) {
freq[c]++;
}
for (auto &p : freq) {
std::cout << p.first << ":" << p.second << " ";
}Solution
Step 1: Count frequencies of each character in string
Characters 'a', 'b', and 'c' each appear twice in "aabbcc".Step 2: Print each character and its count
The loop prints each character and its frequency, so output is "a:2 b:2 c:2 ".Final Answer:
a:2 b:2 c:2 -> Option AQuick Check:
Count 'a','b','c' = 2 each [OK]
- Assuming counts are 1 instead of 2
- Mixing counts between characters
- Confusing output format
std::vector<int> nums = {1, 2, 2, 3};
std::unordered_map freq;
for (int i = 0; i < nums.size(); i++) {
freq[nums[i]] = freq[nums[i]] + 1;
}
for (auto p : freq) {
std::cout << p.first << ":" << p.second << " ";
}Solution
Step 1: Check frequency counting logic
freq[nums[i]] = freq[nums[i]] + 1; correctly increments count for each element.Step 2: Verify container types and loops
Using index loop and unordered_map is valid and works as intended.Final Answer:
No error; code works correctly -> Option CQuick Check:
Increment freq with freq[key]++ works [OK]
- Thinking freq[key] = freq[key] + 1 causes error
- Confusing unordered_map with unordered_set
- Believing range-based for is mandatory
s1 and s2, which approach using frequency counters correctly checks if s2 is an anagram of s1?std::unordered_map freq1, freq2; for (char c : s1) freq1[c]++; for (char c : s2) freq2[c]++; // What next?
Solution
Step 1: Build frequency maps for both strings
freq1 and freq2 store counts of each character in s1 and s2 respectively.Step 2: Compare frequency maps for exact match
If freq1 and freq2 are equal, s2 is an anagram of s1 because they have same chars with same counts.Final Answer:
Compare freq1 and freq2 maps for equality -> Option AQuick Check:
Anagram check = freq maps equal [OK]
- Only checking keys without counts
- Assuming more keys means anagram
- Using sorting instead of frequency maps
Ready to prove it?
Pass the test and this pattern moves unknown
