Skip to content

Hash Table: Code Templates in 6 Languages

If you have not read the concept guide yet, start there for the intuition and the complexity analysis. This page gives you the code to memorize. Each template covers the same logic in JavaScript, Python, Java, C++, Go, and Ruby. All of them run in

O(N)
time and use
O(N)
space for the map.

Main Template: Frequency Counter

Count the occurrences of each element in a collection. This is the foundation for most other hash table work, from anagram checks to top-k frequency problems.

Use this for Ransom Note and as the first half of Intersection of Two Arrays II.

function frequencyCounter(arr) {
    const freq = new Map();

    for (const item of arr) {
        // Read the existing count, default to 0 for a new key,
        // then write back the incremented value in one step.
        freq.set(item, (freq.get(item) || 0) + 1);
    }

    return freq;
}
Templates only help if you can recall them without staring at the screen. Turn these snippets into flashcards for daily mobile review.

Code Breakdown

Key Variables

  • freq / counts: the map that holds one count per unique element.
  • item / num: the current element being processed.
  • count: the number of times the element has appeared so far.

Visual Mechanism

    graph TD
    A["Empty map"] --> B["Read next element"]
    B --> C{"Is it already a key?"}
    C -->|No| D["Insert with count 1"]
    C -->|Yes| E["Add 1 to its count"]
    D --> F["More elements?"]
    E --> F
    F -->|Yes| B
    F -->|No| G["Return the map"]
  

Critical Sections

The initialization creates the empty map, and the default value matters. Ruby uses Hash.new(0), C++ operator[] inserts a zero for new keys, Java uses getOrDefault, and Python reads with get(item, 0). All of these make the first occurrence of an element count as 1 instead of crashing or counting as 0.

The update step reads the current count, adds 1, and writes it back. In most languages the read and the write happen in the same expression, which is easy to misread under time pressure. Practice reading it as “read, increment, write.”

The loop visits each element exactly once. Nothing else is needed, and the iteration order of the map never matters for counting.

Variations

1. Complement Search

Use this when two elements must satisfy a relation, like two numbers summing to a target. For each element, check whether the element that would complete the pair has been seen, then store the current element.

Time

O(N)
, Space
O(N)
.

Use this for Two Sum .

function complementSearch(nums, target) {
    const seen = new Map();

    for (let i = 0; i < nums.length; i++) {
        const complement = target - nums[i];

        // Check before storing so the current element
        // cannot pair with itself.
        if (seen.has(complement)) {
            return [seen.get(complement), i];
        }

        seen.set(nums[i], i);
    }

    return [];
}

2. Grouping Pattern

Use this when elements share a canonical form, like anagrams sharing sorted letters. The canonical form becomes the key, and each key collects a list.

Time

O(N)
plus the cost of building each key, Space
O(N)
.

Use this for Group Anagrams .

function groupByKey(arr, keyFunction) {
    const groups = new Map();

    for (const item of arr) {
        const key = keyFunction(item);

        // Insert an empty list on first sight of a key,
        // then append. The list must exist before the push.
        if (!groups.has(key)) {
            groups.set(key, []);
        }
        groups.get(key).push(item);
    }

    return Array.from(groups.values());
}

3. Count-Down Comparison

Use this when one collection must be built from another, like a ransom note from a magazine. Count the source collection, then decrement counts while consuming the target.

Time

O(N)
, Space
O(N)
.

function canBeBuilt(target, source) {
    const counts = new Map();

    for (const ch of source) {
        counts.set(ch, (counts.get(ch) || 0) + 1);
    }

    for (const ch of target) {
        // A missing key or an exhausted count means
        // the source cannot supply this character.
        if (!counts.has(ch) || counts.get(ch) === 0) {
            return false;
        }
        counts.set(ch, counts.get(ch) - 1);
    }

    return true;
}
Each variation above is a separate review card in the app. Drill them individually so you do not mix up the conditions under pressure.

Now head to the practice problems to apply these templates to real interview questions.

Now that you have the templates, the next step is application. Head to the practice problems or start reviewing these templates with spaced repetition .