Bird
Raised Fist0
DSA Goprogramming

Why Hash Map Exists and What Problem It Solves in DSA Go - Why This Pattern

Choose your learning style10 modes available
Mental Model
A hash map helps us find things quickly by using a special code to jump straight to the answer instead of searching one by one.
Analogy: Imagine a huge library where books are arranged randomly. Without a map, you must check every shelf to find a book. A hash map is like a magical index that tells you exactly which shelf and spot the book is on, so you go straight there.
Array: [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
Keys:   k1  k2  k3  k4  k5  k6  k7  k8
Values: v1  v2  v3  v4  v5  v6  v7  v8
Hash:   h(k1) -> index 2
        h(k2) -> index 5
        h(k3) -> index 2 (collision)
        ...
Dry Run Walkthrough
Input: Store and find phone numbers by name: Add (Alice, 123), (Bob, 456), (Carol, 789), then find Bob's number.
Goal: Show how a hash map lets us find Bob's number quickly without checking every entry.
Step 1: Calculate hash for 'Alice' to find storage index
[ ] [ ] [Alice->123] [ ] [ ] [ ] [ ] [ ]
Why: We use a hash function to convert 'Alice' into an index to store her number quickly.
Step 2: Calculate hash for 'Bob' and store his number
[ ] [ ] [Alice->123] [ ] [ ] [Bob->456] [ ] [ ]
Why: Hash function gives an index for 'Bob' so we store his number directly there.
Step 3: Calculate hash for 'Carol' which collides with 'Alice', store in same index using chaining
[ ] [ ] [Alice->123 -> Carol->789] [ ] [ ] [Bob->456] [ ] [ ]
Why: Collision happens when two keys map to same index; we link them in a list to keep both.
Step 4: Find 'Bob' by hashing and directly accessing index
[ ] [ ] [Alice->123 -> Carol->789] [ ] [ ] [Bob->456] [ ] [ ]
Why: Hash map lets us jump directly to Bob's number without searching all entries.
Result:
[ ] [ ] [Alice->123 -> Carol->789] [ ] [ ] [Bob->456] [ ] [ ]
Found Bob's number: 456
Annotated Code
DSA Go
package main

import (
	"fmt"
)

// Entry holds key-value pairs
type Entry struct {
	key   string
	value int
	next  *Entry
}

// HashMap with fixed size array and chaining for collisions
type HashMap struct {
	buckets []*Entry
	size    int
}

// NewHashMap creates a new hash map
func NewHashMap(size int) *HashMap {
	return &HashMap{
		buckets: make([]*Entry, size),
		size:    size,
	}
}

// hash function converts key to index
func (hm *HashMap) hash(key string) int {
	hash := 0
	for _, ch := range key {
		hash += int(ch)
	}
	return hash % hm.size
}

// Put adds or updates key-value
func (hm *HashMap) Put(key string, value int) {
	index := hm.hash(key) // get index
	entry := hm.buckets[index]
	if entry == nil {
		hm.buckets[index] = &Entry{key: key, value: value}
		return
	}
	// handle collision by chaining
	for entry != nil {
		if entry.key == key {
			entry.value = value // update existing
			return
		}
		if entry.next == nil {
			break
		}
		entry = entry.next
	}
	entry.next = &Entry{key: key, value: value}
}

// Get finds value by key
func (hm *HashMap) Get(key string) (int, bool) {
	index := hm.hash(key) // get index
	entry := hm.buckets[index]
	for entry != nil {
		if entry.key == key {
			return entry.value, true
		}
		entry = entry.next
	}
	return 0, false
}

func main() {
	hm := NewHashMap(8)
	hm.Put("Alice", 123)
	hm.Put("Bob", 456)
	hm.Put("Carol", 789)

	value, found := hm.Get("Bob")
	if found {
		fmt.Printf("Found Bob's number: %d\n", value)
	} else {
		fmt.Println("Bob not found")
	}
}
index := hm.hash(key) // get index
convert key to index to find bucket
if entry == nil { hm.buckets[index] = &Entry{key: key, value: value} return }
store new entry if bucket empty
for entry != nil { if entry.key == key { entry.value = value return } if entry.next == nil { break } entry = entry.next }
handle collision by chaining and update if key exists
entry.next = &Entry{key: key, value: value}
add new entry at end of chain for collision
for entry != nil { if entry.key == key { return entry.value, true } entry = entry.next }
search chain for key to get value
OutputSuccess
Found Bob's number: 456
Complexity Analysis
Time: O(1) average because hashing lets us jump directly to the bucket; worst case O(n) if many collisions chain up
Space: O(n) because we store all entries in buckets and chains
vs Alternative: Compared to searching a list O(n), hash map is much faster on average by avoiding full scans
Edge Cases
Empty hash map
Get returns not found immediately
DSA Go
for entry != nil { if entry.key == key { return entry.value, true } entry = entry.next }
Collision with multiple keys
Entries chain in linked list at same bucket
DSA Go
entry.next = &Entry{key: key, value: value}
Update existing key
Value is replaced without adding new entry
DSA Go
if entry.key == key { entry.value = value return }
When to Use This Pattern
When you need very fast lookup by key and want to avoid slow searches, reach for hash map because it uses hashing to jump directly to data.
Common Mistakes
Mistake: Ignoring collisions and overwriting entries
Fix: Implement chaining or another collision method to store multiple entries per bucket
Mistake: Not updating existing keys and adding duplicates
Fix: Check keys in chain and update value if key matches instead of adding new
Summary
Hash map stores key-value pairs for fast lookup using a hash function.
Use hash maps when you want quick access to data by keys without scanning everything.
The key insight is hashing converts keys into indexes so you jump directly to the data.

Practice

(1/5)
1. Why do we use a hash map instead of a simple list to store key-value pairs?
easy
A. Because lists use less memory than hash maps
B. Because hash maps store data in sorted order automatically
C. Because hash maps provide faster search for keys than lists
D. Because lists can only store numbers, not keys

Solution

  1. Step 1: Understand list search time

    Searching for a key in a list requires checking each element one by one, which takes time proportional to the list size.
  2. Step 2: Understand hash map search time

    Hash maps use a hash function to find the key's location quickly, making search much faster on average.
  3. Final Answer:

    Because hash maps provide faster search for keys than lists -> Option C
  4. Quick Check:

    Hash map = fast key search [OK]
Hint: Hash maps speed up key lookup compared to lists [OK]
Common Mistakes:
  • Thinking lists are faster for key search
  • Believing hash maps store data sorted
  • Confusing memory use with speed
2. Which of the following is the correct way to declare a hash map in Go to store string keys and integer values?
easy
A. var m map[int]string = make(map[string]int)
B. var m map[string]int = make(map[string]int)
C. var m map[string]int = []string{}
D. var m map[string]int = {}

Solution

  1. Step 1: Check map declaration syntax in Go

    In Go, a map is declared with 'var m map[keyType]valueType' and initialized with make().
  2. Step 2: Validate each option

    var m map[string]int = make(map[string]int) correctly declares and initializes a map with string keys and int values. var m map[int]string = make(map[string]int) has mismatched types. var m map[string]int = []string{} uses slice syntax incorrectly. var m map[string]int = {} uses invalid initialization syntax.
  3. Final Answer:

    var m map[string]int = make(map[string]int) -> Option B
  4. Quick Check:

    Go map syntax = var m map[string]int = make(map[string]int) [OK]
Hint: Use make() to initialize maps in Go [OK]
Common Mistakes:
  • Using slice syntax instead of map
  • Mismatching key and value types
  • Forgetting to initialize with make()
3. What will be the output of the following Go code snippet?
m := make(map[string]int)
m["apple"] = 5
m["banana"] = 3
fmt.Println(m["apple"] + m["banana"])
medium
A. Compilation error
B. 53
C. 0
D. 8

Solution

  1. Step 1: Understand map assignments

    The map 'm' stores integer values for keys "apple" and "banana" as 5 and 3 respectively.
  2. Step 2: Calculate the sum of values

    Adding m["apple"] (5) and m["banana"] (3) results in 8.
  3. Final Answer:

    8 -> Option D
  4. Quick Check:

    5 + 3 = 8 [OK]
Hint: Sum values by accessing keys directly [OK]
Common Mistakes:
  • Concatenating values as strings
  • Expecting zero for existing keys
  • Thinking code has syntax errors
4. Identify the error in this Go code that uses a hash map:
m := make(map[string]int)
m["cat"] = 2
fmt.Println(m["dog"])
medium
A. Accessing a key that does not exist returns zero value, no error
B. Map must be declared with var keyword
C. Keys must be integers, not strings
D. Cannot print map values directly

Solution

  1. Step 1: Check map initialization and usage

    The map is correctly initialized and assigned a value for key "cat".
  2. Step 2: Understand accessing missing keys

    Accessing m["dog"] returns the zero value for int type, which is 0, without error.
  3. Final Answer:

    Accessing a key that does not exist returns zero value, no error -> Option A
  4. Quick Check:

    Missing key returns zero [OK]
Hint: Missing keys return zero value, no runtime error [OK]
Common Mistakes:
  • Expecting runtime error on missing key
  • Thinking keys must be integers
  • Confusing map declaration syntax
5. You want to count how many times each word appears in a list of strings using a hash map in Go. Which approach correctly solves this problem?
hard
A. Initialize map[string]int, loop words, increment count for each word key
B. Use a slice of strings and append words, then count manually
C. Use a map[int]string with word counts as keys
D. Sort the list and count duplicates without a map

Solution

  1. Step 1: Understand the counting problem

    We need to track how many times each word appears, so keys are words and values are counts.
  2. Step 2: Choose correct data structure and method

    A map with string keys and int values lets us increment counts easily while looping through words.
  3. Step 3: Evaluate other options

    Use a slice of strings and append words, then count manually uses a slice which is inefficient for counting. Use a map[int]string with word counts as keys swaps keys and values incorrectly. Sort the list and count duplicates without a map avoids map but is less efficient and more complex.
  4. Final Answer:

    Initialize map[string]int, loop words, increment count for each word key -> Option A
  5. Quick Check:

    Map counts words efficiently [OK]
Hint: Use map[word]count and increment in loop [OK]
Common Mistakes:
  • Using wrong map key/value types
  • Trying to count with slices only
  • Ignoring map benefits for counting
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard