Frequency Counter Pattern Using Hash Map in DSA Javascript - Time & Space Complexity
We want to know how fast the frequency counter pattern runs when counting items.
How does the time grow as the list gets bigger?
Analyze the time complexity of the following code snippet.
function frequencyCounter(arr) {
const freq = {};
for (const item of arr) {
freq[item] = (freq[item] || 0) + 1;
}
return freq;
}
This code counts how many times each item appears in the list.
- Primary operation: One loop over the array items.
- How many times: Exactly once for each item in the array.
As the list gets bigger, the loop runs more times, once per item.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The work grows directly with the number of items.
Time Complexity: O(n)
This means the time to count frequencies grows in a straight line with the list size.
[X] Wrong: "Using a hash map makes the code slower because of extra steps."
[OK] Correct: The hash map lets us count items in one pass, so it actually saves time compared to checking each item multiple times.
Knowing how to count items quickly is a key skill. It shows you can use simple tools to solve problems efficiently.
"What if we used nested loops to count frequencies instead of a hash map? How would the time complexity change?"
Practice
Solution
Step 1: Understand frequency counter pattern
The frequency counter pattern uses a hash map to store counts of each item in a collection.Step 2: Identify the purpose
Counting occurrences helps to quickly check how many times each item appears.Final Answer:
To count how many times each item appears in a collection -> Option DQuick Check:
Frequency counter = count items [OK]
- Confusing frequency counting with sorting
- Thinking it removes duplicates instead of counting
- Assuming it reverses arrays
Solution
Step 1: Identify correct data structure for frequency counter
A frequency counter uses an object (hash map) to store keys and counts.Step 2: Choose correct initialization syntax
In JavaScript, an empty object is created with curly braces {}.Final Answer:
const freq = {}; -> Option BQuick Check:
Empty object = {} [OK]
- Using array [] instead of object {}
- Assigning null or 0 which are not objects
- Confusing object with other data types
const arr = ['a', 'b', 'a', 'c', 'b', 'a'];
const freq = {};
for (const char of arr) {
freq[char] = (freq[char] || 0) + 1;
}
console.log(freq);Solution
Step 1: Loop through array and count characters
Each character's count is incremented in freq object: 'a' appears 3 times, 'b' 2 times, 'c' 1 time.Step 2: Construct final frequency object
freq = {"a": 3, "b": 2, "c": 1} after loop ends.Final Answer:
{"a": 3, "b": 2, "c": 1} -> Option AQuick Check:
Count 'a' = 3, 'b' = 2, 'c' = 1 [OK]
- Mixing counts of 'a' and 'b'
- Not initializing counts properly
- Using arrays instead of objects for counting
const arr = ['x', 'y', 'x', 'z'];
const freq = {};
for (let i = 0; i < arr.length; i++) {
freq[arr[i]] += 1;
}
console.log(freq);Solution
Step 1: Understand the error cause
freq[arr[i]] is undefined initially, so adding 1 causes NaN.Step 2: Fix by initializing count
Set freq[arr[i]] = 0 if undefined before adding 1.Final Answer:
Initialize freq[arr[i]] to 0 before adding 1 -> Option AQuick Check:
Initialize before increment to avoid NaN [OK]
- Trying to push to object as if array
- Ignoring undefined initial values
- Changing loop type unnecessarily
arr1 = [1, 2, 2, 3] and arr2 = [2, 3, 3, 4], which code snippet correctly checks if arr2 contains the same frequency of elements as arr1 using the frequency counter pattern?Solution
Step 1: Understand frequency comparison logic
We must count frequencies in both arrays and compare counts for each element.Step 2: Analyze each code snippet
const freq = {}; for (const num of arr1) freq[num] = (freq[num] || 0) + 1; for (const num of arr2) freq[num] -= 1; for (const key in freq) { if (freq[key] !== 0) return false; } return true; This uses a single object: increments for arr1, decrements for arr2 (NaN for extras), checks all zero. Handles extras (NaN≠0), shortages (positive≠0), overcounts (negative≠0).Final Answer:
const freq = {}; increment arr1, decrement arr2, check all zero -> Option CQuick Check:
Single freq: +arr1, -arr2, all zero? [OK]
- Not comparing all keys in both frequency counters
- Overwriting counts instead of incrementing
- Using single frequency object incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
