HashMap Implementation from Scratch in DSA Go - Time & Space Complexity
When building a HashMap from scratch, it is important to understand how fast it can add and find items.
We want to know how the time to do these actions changes as we add more items.
Analyze the time complexity of the following code snippet.
func (h *HashMap) Put(key string, value int) {
index := h.hash(key) % len(h.buckets)
for i := 0; i < len(h.buckets[index]); i++ {
if h.buckets[index][i].key == key {
h.buckets[index][i].value = value
return
}
}
h.buckets[index] = append(h.buckets[index], entry{key, value})
}
This code adds or updates a key-value pair in a HashMap using separate chaining to handle collisions.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop through the bucket list at the hashed index to find the key.
- How many times: Up to the number of entries in that bucket, which depends on collisions.
As more items are added, buckets may have more entries, making the loop longer.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Few entries per bucket, loop runs about 1-2 times |
| 100 | More entries, loop runs several times if collisions occur |
| 1000 | Many entries, loop can run many times if buckets are uneven |
Pattern observation: If the hash spreads keys well, the loop stays short; otherwise, it grows with n.
Time Complexity: O(1) on average, O(n) in worst case
On average, adding or finding a key takes constant time, but if many keys collide, it can take time proportional to the number of keys.
[X] Wrong: "HashMap operations always take the same short time no matter what."
[OK] Correct: If many keys end up in the same bucket, the operation slows down because it must check many entries.
Understanding how HashMaps work under the hood helps you explain why they are fast and when they might slow down, a key skill in coding interviews.
"What if we changed the collision handling from separate chaining to open addressing? How would the time complexity change?"
Practice
HashMap in data structures?Solution
Step 1: Understand the role of HashMap
A HashMap stores data as key-value pairs, allowing quick access to values using keys.Step 2: Compare with other data structures
Unlike arrays or lists, HashMaps do not store data sequentially or sorted but focus on fast lookup.Final Answer:
To store key-value pairs for fast data retrieval -> Option AQuick Check:
HashMap = key-value fast access [OK]
- Confusing HashMap with arrays or lists
- Thinking HashMap stores data in order
- Assuming HashMap is for mathematical operations
Solution
Step 1: Understand Go map declaration
In Go, maps are created using make function: make(map[keyType]valueType).Step 2: Check each option
A declares a nil map which cannot be used for assignments. B has invalid syntax (cannot assign type as value). C has incorrect syntax (cannot call map type as function). D uses make correctly.Final Answer:
var m = make(map[string]int) -> Option AQuick Check:
Use make() to create maps in Go [OK]
- Declaring without initializing (nil map)
- Using map type without literal or make
- Trying to call map as a function
package main
import "fmt"
func main() {
m := make(map[string]int)
m["apple"] = 5
m["banana"] = 3
m["apple"] = 7
fmt.Println(m["apple"])
}Solution
Step 1: Analyze map insertions
Initially, "apple" is set to 5, then updated to 7, so the last value is 7.Step 2: Print the value for key "apple"
Printing m["apple"] outputs the updated value 7.Final Answer:
7 -> Option DQuick Check:
Last assigned value for key is returned [OK]
- Assuming first value remains after update
- Confusing zero value with stored value
- Expecting compilation error due to reassignment
package main
import "fmt"
func main() {
var m map[string]int
m["key"] = 10
fmt.Println(m["key"])
}Solution
Step 1: Check map initialization
The map variable m is declared but not initialized with make(), so it is nil.Step 2: Understand assignment to nil map
Assigning to a nil map causes runtime panic because map is not ready to store data.Final Answer:
Map is not initialized before use -> Option BQuick Check:
Maps must be initialized with make() before assignment [OK]
- Forgetting to initialize map before use
- Assuming declaration alone creates map
- Confusing map initialization with slice
Solution
Step 1: Understand collision in HashMap
When two keys hash to the same bucket, collision occurs and must be handled to store both pairs.Step 2: Evaluate collision handling methods
Using a linked list at each bucket allows storing multiple pairs safely. Overwriting loses data, ignoring collisions loses data, and fixed arrays without hashing lose efficiency.Final Answer:
Use a linked list at each bucket to store multiple key-value pairs -> Option CQuick Check:
Separate chaining with linked lists handles collisions [OK]
- Overwriting values on collision
- Ignoring collisions causing data loss
- Not using hashing for key distribution
Ready to prove it?
Pass the test and this pattern moves unknown
