LINEAR DATA STRUCTURES / ALGORITHM BRIEF

Hash map

A hash map stores key-value pairs and supports insert, lookup, and delete in O(1) on average.

BeginnerPhase 02 / Topic 7 of 8Mental modelComplexityEdge cases
01

Overview

A hash map stores key-value pairs and supports insert, lookup, and delete in O(1) on average. A hash function converts the key into an integer, which picks a bucket in an internal array. Collisions (two keys in one bucket) are handled by chaining or probing.

Hash maps are the most common tool for turning an O(n^2) solution into O(n). Whenever you catch yourself searching for something you saw earlier, ask: can I remember it in a map?

A coat check with numbered hooks

The attendant turns your ticket number into a hook position instantly and walks straight to it. If two coats share a hook, they hang one behind the other and the attendant checks the few coats there. Lookup does not depend on how many coats are in the room.

02

When to use it

  • You need to remember something about earlier elements: indexes, counts, prefix sums.
  • Counting frequencies of characters, words, or numbers.
  • Grouping items by a computed key (anagrams, same pattern).
  • Caching / memoization of computed results.
  • Building an index from an ID to an object.
03

Problem patterns it solves

Complement lookup

Recognize it when: find two elements that combine to a target.

  • 1. Two Sum
  • 454. 4Sum II
  • 2215. Find the Difference of Two Arrays
  • 350. Intersection of Two Arrays II
Frequency counting

Recognize it when: most frequent, first unique, majority, equalize frequencies.

  • 387. First Unique Character in a String
  • 347. Top K Frequent Elements
  • 2423. Remove Letter To Equalize Frequency
  • 1207. Unique Number of Occurrences
Group by canonical key

Recognize it when: anagrams, isomorphic strings, same shape.

  • 49. Group Anagrams
  • 205. Isomorphic Strings
  • 290. Word Pattern
Prefix sum + map

Recognize it when: count subarrays with sum k or divisible by k.

  • 560. Subarray Sum Equals K
  • 1248. Count Number of Nice Subarrays
  • 974. Subarray Sums Divisible by K
  • 525. Contiguous Array
Index tracking

Recognize it when: last seen position, nearby duplicates, longest span.

  • 219. Contains Duplicate II
  • 3. Longest Substring Without Repeating Characters
  • 128. Longest Consecutive Sequence
Design with maps

Recognize it when: O(1) operations on custom structures.

  • 146. LRU Cache
  • 380. Insert Delete GetRandom O(1)
  • 706. Design HashMap
04

Where it is used in real software

Caches

Redis and Memcached are distributed hash maps from key to value; application caches are in-memory maps.

Database hash indexes and joins

Hash joins build a map from join key to rows of the smaller table, then probe it with each row of the larger table.

Language runtimes

JavaScript objects, Python dicts, and symbol tables in compilers are hash maps; V8 falls back to dictionary mode for objects with many dynamic keys.

Deduplication

Content-addressed storage (Git objects, Docker layers) looks up data by its hash to avoid storing duplicates.

05

Key terms

Hash function
Maps a key to an integer. Must be deterministic; good ones spread keys uniformly.
Bucket
Slot in the internal array chosen by hash(key) mod capacity.
Collision
Two different keys map to the same bucket.
Load factor
entries / buckets. When it passes a threshold (0.75 in Java), the table resizes.
Rehashing
Allocating a larger array and reinserting every entry; amortized O(1) per insert.
06

What happens on put(key, value)

  1. 1
    Hash the key

    Compute key.hashCode() (Java) or the engine's internal hash.

  2. 2
    Pick the bucket

    index = hash mod capacity (Java uses hash & (capacity - 1) with a power-of-two capacity).

  3. 3
    Search the bucket

    Compare keys with equals. If found, replace the value.

  4. 4
    Insert

    Otherwise add a new entry to the bucket's chain.

  5. 5
    Resize if needed

    If the load factor is exceeded, double the capacity and redistribute all entries.

07

Two Sum with a hash map

nums = [2, 7, 11, 15], target = 9

Step 1 / 2
inums[i]Need (target - nums[i])Seen map beforeAction
027{}7 not seen, store 2 -> 0
172{2: 0}2 seen at index 0, return [0, 1]

NOWi: 0 | nums[i]: 2 | Need (target - nums[i]): 7 | Seen map before: {} | Action: 7 not seen, store 2 -> 0

The map remembers every value already passed, so each element needs one O(1) lookup: O(n) total instead of checking all pairs in O(n^2).

08

Implementation

// Use Map, not {}: any key type, reliable size, no prototype keysfunction twoSum(nums, target) {  const seen = new Map();  for (let i = 0; i < nums.length; i++) {    const need = target - nums[i];    if (seen.has(need)) return [seen.get(need), i];    seen.set(nums[i], i);  }  return [];} function groupAnagrams(words) {  const groups = new Map();  for (const word of words) {    const counts = new Array(26).fill(0);    for (const ch of word) counts[ch.charCodeAt(0) - 97]++;    const key = counts.join("#"); // O(k) key instead of sorting O(k log k)    if (!groups.has(key)) groups.set(key, []);    groups.get(key).push(word);  }  return [...groups.values()];} // 1248. Count Number of Nice Subarrays (exactly k odd numbers)function numberOfSubarrays(nums, k) {  const countByOdds = new Map([[0, 1]]);  let odds = 0, result = 0;  for (const x of nums) {    if (x % 2 === 1) odds++;    result += countByOdds.get(odds - k) ?? 0;    countByOdds.set(odds, (countByOdds.get(odds) ?? 0) + 1);  }  return result;} function longestConsecutive(nums) {  const set = new Set(nums);  let best = 0;  for (const x of set) {    if (set.has(x - 1)) continue; // only start at the beginning of a run    let length = 1;    while (set.has(x + length)) length++;    best = Math.max(best, length);  }  return best;}
09

Complexity and performance

get / put / deleteO(1) average

With a good hash function and resizing.

Worst caseO(n) / O(log n)

All keys collide; Java 8+ trees large buckets, giving O(log n).

IterationO(n + capacity)

Visits every bucket.

SpaceO(n)

Plus unused bucket capacity.

10

Trade-offs

Hash map vs sorted map

HashMap is O(1) but unordered. TreeMap (red-black tree) is O(log n) but supports floor, ceiling, and ordered iteration.

Hash map vs array

If keys are small integers or letters, an array index is faster and uses less memory.

Memory overhead

Each entry stores the key, value, hash, and a next pointer; Java boxing of int keys adds more.

11

Variants and related techniques

Separate chaining

Each bucket holds a list of entries (Java HashMap).

Open addressing

Collisions probe other slots in the same array (Python dict, many C++ maps).

LinkedHashMap

Preserves insertion or access order; JS Map also iterates in insertion order.

Counter / multiset

A map from item to count; Java uses map.merge(key, 1, Integer::sum).

12

Common mistakes

  • Using a JS object {} as a map with arbitrary keys.

    Fix: Object keys become strings and inherit prototype properties like 'constructor'. Use Map.

  • Mutable objects as keys.

    Fix: If a key's hash changes after insertion, it can never be found again. Use immutable keys.

  • Overriding equals without hashCode in Java.

    Fix: Equal objects must have equal hash codes, or lookups fail.

  • Comparing Integer values with == in Java.

    Fix: Boxed Integers above 127 are different objects; use .equals or unbox.

13

Interview questions

Why is a hash map O(1) on average but O(n) worst case?

A good hash spreads keys evenly, so each bucket holds a constant number of entries. If many keys collide into one bucket, a lookup must scan them all.

What happens when a hash map resizes?

It allocates a larger bucket array (usually double) and reinserts every entry. That single operation is O(n), but it happens rarely enough that insert stays amortized O(1).

How do you design a hash map from scratch?

An array of buckets, a hash function mapping keys to indexes, chaining or probing for collisions, and resizing when the load factor exceeds a threshold.

14

Practice problems

ProblemDifficultyWhat it trains
1. Two SumEasyComplement lookup.
350. Intersection of Two Arrays IIEasyFrequency counts.
49. Group AnagramsMediumCanonical keys.
560. Subarray Sum Equals KMediumPrefix sums in a map.
1248. Count Number of Nice SubarraysMediumPrefix count of odds.
128. Longest Consecutive SequenceMediumStart only at run beginnings.
706. Design HashMapEasyBuckets and chaining.