← All patterns

Hash Maps

Constant-time keyed lookup. Frequency counting, complement search, anagram grouping, two-sum, and running aggregations keyed by computed signatures — the most reused primitive in the entire toolkit.

29 problems 13 Easy 13 Medium 3 Hard

Constant-time keyed lookup is the most-reused primitive in DSA. Use hash maps for frequency counting, complement search (two-sum), grouping by signature (anagrams via sorted-string key), and rolling state by computed key (prefix-sum, modular hash).

The design question is the *key* — picking a canonical form so that 'same logical thing' hashes equally is the whole game.

When to reach for this pattern

  • Look up 'have I seen this value before?'
  • Group items by a derived property (anagram, signature)
  • Count occurrences and act on the count
  • Two-sum-like complement searches

Canonical template

// complement search
unordered_map<int, int> seen;
for (int i = 0; i < (int)nums.size(); ++i) {
    int need = target - nums[i];
    if (auto it = seen.find(need); it != seen.end())
        return {it->second, i};
    seen[nums[i]] = i;
}

// group anagrams by sorted-string key
unordered_map<string, vector<string>> groups;
for (auto& s : strs) {
    string key = s;
    sort(key.begin(), key.end());
    groups[key].push_back(s);
}

C++ · adapt the names and types to your problem.

Common pitfalls

  • Order of insertion vs lookup matters — inserting first means using a value to find itself
  • Hash collisions on adversarial inputs degrade to O(n) — competitive code may need salted maps
  • Choosing a poor key (non-canonical) groups distinct things or splits identical things
  • unordered_map<> iteration order is implementation-defined — don't rely on it

Related patterns

Problems (29)

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.