Skip to content
← Back to Blog

Hash Map Patterns for Coding Interviews: The Essential Guide

10 min read

If you could only bring one data structure to a coding interview, it should be a hash map. Hash maps (dictionaries in Python, objects or Maps in JavaScript) give you O(1) average-case lookup, insertion, and deletion. That single property unlocks dozens of interview problems — from the classic Two Sum to prefix-sum tricks to LRU Cache design. In this guide, you will learn five battle-tested hash map patterns, see full Python walkthroughs for three key problems, and get a practice list of 10 problems organized by pattern type.

Why Hash Maps Are the #1 Interview Tool

Most brute-force interview solutions involve nested loops — scanning the array once to pick an element, then scanning again to find its complement or match. That is O(n²). A hash map eliminates the inner loop by letting you answer "have I seen this value before?" in O(1) time.

The Complement Trick

Instead of searching for a pair that sums to a target, compute the complement (target − current) and look it up in the hash map. If it exists, you found your answer. If not, store the current value and move on. This single idea powers Two Sum, Subarray Sum Equals K, and many more.

  • O(1) lookup — turn O(n²) brute-force into O(n) single-pass solutions.
  • Flexible keys — strings, tuples, frozen sets — anything hashable can be a key.
  • Counts & indices — store frequencies, last-seen indices, or prefix sums as values.

5 Essential Hash Map Patterns

Pattern 1 — Frequency Counting

Count how often each element appears, then use those counts to answer the question. This is the most common hash map pattern and appears in anagram checks, top-K problems, and majority element.

Classic problems: LC 242 Valid Anagram, LC 347 Top K Frequent Elements, LC 169 Majority Element.

# Frequency counting template
from collections import Counter

def is_anagram(s: str, t: str) -> bool:
    return Counter(s) == Counter(t)

Learn more on our Hash Map Counting pattern page.

Pattern 2 — Two Sum / Complement Pattern

Store each element (or a running value) in a hash map as you iterate. At each step, check whether the complement needed to satisfy the condition already exists in the map. This converts an O(n²) scan into a single O(n) pass.

Classic problems: LC 1 Two Sum, LC 560 Subarray Sum Equals K, LC 454 4Sum II.

Explore our Two Sum Pattern deep-dive.

Pattern 3 — Grouping / Bucketing

Use a hash map where the key represents a canonical form and the value is a list of items sharing that key. The trick is choosing the right key — sorted characters for anagrams, digit patterns for phone number groups, etc.

Classic problems: LC 49 Group Anagrams, LC 249 Group Shifted Strings, LC 609 Find Duplicate File in System.

Pattern 4 — Caching / Memoization

Use a hash map to cache previously computed results so you never recompute the same subproblem. This is the heart of top-down DP and shows up in design problems like LRU Cache where you need O(1) access to cached entries.

Classic problems: LC 146 LRU Cache, LC 380 Insert Delete GetRandom O(1), LC 706 Design HashMap.

Pattern 5 — Sliding Window + Hash Map

Combine a sliding window with a hash map to track the state of the current window. The hash map counts character frequencies or distinct elements, while the window pointers control which portion of the input is active.

Classic problems: LC 3 Longest Substring Without Repeating Characters, LC 76 Minimum Window Substring, LC 438 Find All Anagrams in a String.

See how these patterns combine in our Hash Map vs Two Sum comparison.

Hash Map vs Hash Set — When to Use Which

Hash Map (dict)

Stores key → value pairs. Use when you need to associate data with each key: counts, indices, prefix sums, or lists of grouped items. dict in Python, Map in JavaScript.

Hash Set (set)

Stores only keys — no associated value. Use for pure membership checks: "have I seen this element?", "is this a duplicate?", or "does this value exist?". Slightly more memory-efficient when you do not need values.

Rule of thumb: if you only care about existence, use a set. If you need to store extra information (count, index, list), use a map.

Step-by-Step Examples with Python Code

Example 1 — Two Sum (LC 1)

Given an array of integers nums and a target, return the indices of the two numbers that add up to the target. Each input has exactly one solution.

Approach: Iterate through the array. For each element, compute the complement (target − current). If the complement exists in our hash map, return both indices. Otherwise, store {current_value: index}.

def two_sum(nums: list[int], target: int) -> list[int]:
    seen = {}  # value -> index
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i
    return []

# Walkthrough with nums = [2, 7, 11, 15], target = 9
# i=0: complement = 9-2 = 7, seen={} → not found → seen={2:0}
# i=1: complement = 9-7 = 2, seen={2:0} → FOUND → return [0, 1]

Time: O(n) — single pass. Space: O(n) — hash map stores at most n entries.

Example 2 — Group Anagrams (LC 49)

Given a list of strings, group the anagrams together. Two strings are anagrams if they contain the same characters in different order.

Key insight: Anagrams share the same sorted character sequence. Use the sorted string as the hash map key and append each original string to the corresponding bucket.

from collections import defaultdict

def group_anagrams(strs: list[str]) -> list[list[str]]:
    groups = defaultdict(list)
    for s in strs:
        key = tuple(sorted(s))  # canonical form
        groups[key].append(s)
    return list(groups.values())

# Input:  ["eat", "tea", "tan", "ate", "nat", "bat"]
# Keys:   ('a','e','t') → ["eat","tea","ate"]
#         ('a','n','t') → ["tan","nat"]
#         ('a','b','t') → ["bat"]

Time: O(n · k log k) where k is the max string length. Space: O(n · k).

Optimization: Instead of sorting, use a 26-element count tuple as the key for O(n · k) time — useful when strings are very long.

Example 3 — Subarray Sum Equals K (LC 560)

Given an integer array and a target k, return the total number of continuous subarrays whose sum equals k. The array may contain negative numbers, so sliding window alone will not work.

Key insight: Use the prefix sum + hash map combo. If prefix[j] − prefix[i] = k, the subarray from i+1 to j sums to k. Store prefix sum frequencies in a hash map and look up (current_prefix − k) at each step.

def subarray_sum(nums: list[int], k: int) -> int:
    count = 0
    prefix = 0
    prefix_counts = {0: 1}  # base case: empty prefix

    for num in nums:
        prefix += num
        # How many earlier prefixes satisfy prefix - earlier = k?
        count += prefix_counts.get(prefix - k, 0)
        prefix_counts[prefix] = prefix_counts.get(prefix, 0) + 1

    return count

# Walkthrough with nums = [1, 2, 3], k = 3
# prefix=1: look up 1-3=-2 → 0. Store {0:1, 1:1}
# prefix=3: look up 3-3= 0 → 1. count=1. Store {0:1, 1:1, 3:1}
# prefix=6: look up 6-3= 3 → 1. count=2. Store {0:1, 1:1, 3:1, 6:1}
# Answer: 2 → subarrays [1,2] and [3]

Time: O(n). Space: O(n). This prefix sum + hash map combo is one of the most versatile techniques in competitive programming and interviews.

Common Mistakes to Avoid

  • Mutating the map while iterating: In Python, adding or deleting keys during a for loop over a dict raises a RuntimeError. Build a separate list of keys to process, or iterate over a copy.
  • Using unhashable keys: Lists and sets are mutable and cannot be dict keys in Python. Convert them to tuples or frozensets first. A common bug in Group Anagrams is trying to use a list as a key.
  • Forgetting the base case in prefix sum: Always initialize your prefix map with {0: 1}. Without this, subarrays starting at index 0 that sum to k will be missed.
  • Wrong key design: Choosing an ambiguous key leads to false groupings. For example, using character counts as a string like "1,2,3" can collide if the separator appears in the data. Use tuples for safety.
  • Ignoring hash collisions in theory: While Python and Java handle collisions internally, interviewers may ask about worst-case O(n) lookups. Know that amortized O(1) depends on a good hash function and low load factor.

Hash Map + Other Patterns

Hash maps rarely work in isolation. They amplify other patterns by providing O(1) state lookups. Here are the most powerful combos:

Hash Map + Sliding Window

Track character counts inside the window. As the window slides, increment counts for new elements and decrement for removed ones. Used in Longest Substring Without Repeating Characters, Minimum Window Substring, and Permutation in String. See our Sliding Window guide for templates.

Hash Map + Prefix Sum

Store prefix sum frequencies to count subarrays with a target sum in O(n). This works even with negative numbers where sliding window fails. Powers LC 560 Subarray Sum Equals K, LC 525 Contiguous Array, and LC 930 Binary Subarrays With Sum.

Hash Map + Two Pointers

Use a hash map to precompute data, then apply two pointers for the main logic. For example, count character frequencies first, then use two pointers on the sorted result. Read more in Two Pointers vs Sliding Window.

Hash Map + Graph Traversal

Build adjacency lists using a hash map, then traverse with BFS or DFS. Hash maps make graph construction from edge lists O(E) and neighbor lookup O(1). Essential for Clone Graph, Course Schedule, and Word Ladder.

Practice Problems by Pattern

Here are 10 problems organized by the hash map pattern they test. Start with the ones marked Easy, then work up.

Frequency Counting

  1. LC 242 — Valid Anagram (Easy)
  2. LC 347 — Top K Frequent Elements (Medium)
  3. LC 451 — Sort Characters By Frequency (Medium)

Complement / Two Sum

  1. LC 1 — Two Sum (Easy)
  2. LC 560 — Subarray Sum Equals K (Medium)
  3. LC 525 — Contiguous Array (Medium)

Grouping / Bucketing

  1. LC 49 — Group Anagrams (Medium)

Caching / Design

  1. LC 146 — LRU Cache (Medium)
  2. LC 380 — Insert Delete GetRandom O(1) (Medium)

Sliding Window + Hash Map

  1. LC 3 — Longest Substring Without Repeating Characters (Medium)

Continue building your pattern recognition skills with these related guides:

See hash map patterns in action

Paste any LeetCode problem into AlgoArk and instantly see which hash map pattern applies — with step-by-step visual walkthroughs.