Hash Map vs Array vs Linked List for Lookup in DSA Go - Complexity Comparison
We want to understand how fast we can find a value in different data structures.
How does the time to look up a value change as the data grows?
Analyze the time complexity of looking up a value in three data structures.
// Lookup in array
func lookupArray(arr []int, target int) bool {
for _, v := range arr {
if v == target {
return true
}
}
return false
}
// Lookup in linked list
type Node struct {
value int
next *Node
}
func lookupLinkedList(head *Node, target int) bool {
current := head
for current != nil {
if current.value == target {
return true
}
current = current.next
}
return false
}
// Lookup in hash map
func lookupHashMap(m map[int]bool, target int) bool {
_, found := m[target]
return found
}
This code checks if a target value exists in an array, linked list, or hash map.
Look at what repeats when searching for the target.
- Array and Linked List: Loop through each element one by one.
- Hash Map: Directly check if the key exists without looping.
- Dominant operation: The loop over elements in array and linked list.
As the number of items grows, how many checks do we do?
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 checks for array/linked list, 1 for hash map |
| 100 | Up to 100 checks for array/linked list, 1 for hash map |
| 1000 | Up to 1000 checks for array/linked list, 1 for hash map |
Pattern observation: Array and linked list checks grow linearly with input size; hash map checks stay constant.
Time Complexity: O(n) for array and linked list, O(1) average for hash map
In simple words, searching in array or linked list takes longer as data grows, but hash map lookup stays fast.
[X] Wrong: "Hash map lookup always takes the same time no matter what."
[OK] Correct: Sometimes hash maps have collisions causing slower lookups, but on average they are very fast.
Knowing how lookup times differ helps you choose the right data structure and explain your choices clearly.
"What if the array was sorted? How would the time complexity of lookup change?"
Practice
Solution
Step 1: Understand lookup times for each data structure
Hash Map uses hashing to find keys quickly, usually in constant time O(1). Arrays require scanning or index access, O(1) if index known but O(n) if searching by value. Linked Lists require scanning all nodes, O(n).Step 2: Compare average lookup times
Hash Map is fastest on average for key lookup because it directly computes the position. Arrays and Linked Lists are slower for searching by value.Final Answer:
Hash Map -> Option BQuick Check:
Fastest lookup by key = Hash Map [OK]
- Confusing array index access with searching by value
- Assuming linked list lookup is fast
- Thinking stack is a lookup structure
Solution
Step 1: Identify correct Go syntax for hash map declaration
In Go, maps are declared with 'map[keyType]valueType' and initialized with make(). var m map[string]int = make(map[string]int) uses 'map[string]int' and make(), which is correct.Step 2: Check other options for errors
var m = [string]int{} uses array syntax incorrectly. var m = []int{} is a slice, not a map. var m map[int]string = make(map[int]string) has reversed key and value types compared to question.Final Answer:
var m map[string]int = make(map[string]int) -> Option AQuick Check:
Go map syntax = var m map[string]int = make(map[string]int) [OK]
- Using array or slice syntax instead of map
- Not initializing map with make()
- Swapping key and value types
Solution
Step 1: Understand membership check requirements
Membership check means quickly finding if an element exists. For large datasets, speed matters.Step 2: Compare data structures for membership check
Array requires scanning O(n), linked list also O(n). Hash Map uses hashing for average O(1) lookup, best for membership.Final Answer:
Hash Map, because it provides average O(1) lookup time for membership checks -> Option DQuick Check:
Membership check fastest = Hash Map [OK]
- Choosing array or list for fast membership
- Ignoring hash map average O(1) lookup
- Confusing stack with membership structure
package main
import "fmt"
func main() {
arr := []int{10, 20, 30, 40}
m := make(map[int]int)
for i, v := range arr {
m[v] = i
}
fmt.Println(m[30])
}Solution
Step 1: Understand the loop and map assignment
The loop iterates over array elements with index i and value v. It sets m[v] = i, so key is element value, value is index.Step 2: Find the value for key 30 in map
For element 30, index is 2, so m[30] = 2. Printing m[30] outputs 2.Final Answer:
2 -> Option AQuick Check:
m[30] = index 2 [OK]
- Confusing key and value in map
- Expecting output 30 instead of index
- Thinking code has error
package main
import "fmt"
type Node struct {
val int
next *Node
}
func contains(head *Node, target int) bool {
for head != nil {
if head.val == target {
return true
}
head = head.next
}
return false
}
func main() {
var head *Node
head.val = 10
head.next = nil
fmt.Println(contains(head, 10))
}Solution
Step 1: Analyze initialization of head pointer
head is declared as nil pointer. Accessing head.val without allocating Node causes runtime panic (nil pointer dereference).Step 2: Check function and loop correctness
Function contains is correct. Loop condition is correct.Final Answer:
head is nil, so accessing head.val causes runtime panic -> Option CQuick Check:
Nil pointer access causes panic [OK]
- Ignoring nil pointer dereference
- Thinking loop condition is wrong
- Missing import is not main error
Ready to prove it?
Pass the test and this pattern moves unknown
