Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 3 – Arrays and hashing

Grouping with canonical keys

Group anagrams and other equivalent items in one pass with canonical keys: sorted-letter and count keys compared, and keys each language can hash.

  • Intermediate
  • 15 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0 and Java temurin-25.0.4+101.0.LTS
  • By MySmartCoPilot
Free intro, Pro: 4 of 15 minutes free
Free: The problem: words made of the same letters. With a pass: the other 8 sections and 3 interview answers, about 11 minutes.

What you will learn

  • Design a canonical key that equivalent items share and no other items have
  • Group items in one pass with a map from each key to its list of items
  • Compare sorted-letter keys and count keys by their measured cost
  • Choose keys that Python, JavaScript, Java, C++ and Go compare by value
  • Apply canonical keys to shifted words, rotations and shapes on a grid

Before you start

What you’ll learn · Before you start

What you will learn

  • Design a canonical key that equivalent items share and no other items have
  • Group items in one pass with a map from each key to its list of items
  • Compare sorted-letter keys and count keys by their measured cost
  • Choose keys that Python, JavaScript, Java, C++ and Go compare by value
  • Apply canonical keys to shifted words, rotations and shapes on a grid

Before you start

On this page

Grouping with canonical keys puts equivalent items together in one pass over a list. Every item gets a canonical key: A value computed from an item that every item equivalent to it shares and no other item has, such as a word's letters in sorted order for words made of the same letters. that all items equivalent to it share and no other item has, and a hash map files each item under its key, so each group forms as its items arrive: 100,000 words take 100,000 lookups instead of up to 5 × 10⁹ comparisons. For words made of the same letters, known as anagrams, the letters in alphabetical order make such a key: “rate”, “tear” and “tare” all become “aert”. The same idea groups any items once you can say what makes two of them “the same”. The problem known as group anagrams comes next in an original form, a word game with limits, together with the reason why comparing words with each other cannot meet them.

The problem: words made of the same letters

The problem

A word game collects the words its players type in a round. Group the words made of the same letters, each as many times, and return the groups: each group lists its words in the order they were typed, and the groups come in the order of their first words. A word typed twice joins its group twice. Limits: up to 100,000 words, each of 1 to 20 lowercase letters a to z.

  1. ["inch", "rate", "chin", "tear", "chain", "tare", "china"] gives [["inch", "chin"], ["rate", "tear", "tare"], ["chain", "china"]].
  2. ["aa", "a", "aa"] gives [["aa", "aa"], ["a"]]: a repeat stays, and “a” has fewer letters than “aa”.
  3. ["solo"] gives [["solo"]].
Three groups by key: chin holds inch and chin; aert holds rate, tear and tare; achin holds chain and china.Key chinKey aertKey achininchchinrateteartarechainchina

Equivalent words share a key

Text description of the diagram

Each word of the first example gets a key: its letters in alphabetical order. The words with the same key form one group, one row per key:

  • key chin: inch and chin;
  • key aert: rate, tear and tare;
  • key achin: chain and china.

Words with the same key are made of the same letters, so each key stands for one group.

The brute force: compare with every group

Compare each word with the first word of every group formed so far, using the letter-count check of the previous lesson, and add it to the first group that matches, or start a new group. The worst case is a round in which no two words match, so every word is compared with every group:

Comparing each word with every group Python · brute/groups_brute.py
"""Groups of words made of the same letters, by brute force: compare each word with every group so far."""
from collections import Counter
from itertools import combinations_with_replacement


def same_letters(a, b):
    return len(a) == len(b) and Counter(a) == Counter(b)


def group_brute(words):
    """Returns (groups, comparisons): each word joins the first group whose first word has the same letters."""
    groups = []
    comparisons = 0
    for word in words:
        for group in groups:
            comparisons += 1
            if same_letters(group[0], word):
                group.append(word)
                break
        else:
            groups.append([word])
    return groups, comparisons


print(group_brute(["inch", "rate", "chin", "tear", "chain", "tare", "china"])[0])
print(group_brute(["aa", "a", "aa"])[0])
print(group_brute(["solo"])[0])

# The slowest case: every word is its own group, so each word is compared with every group before it.
classes = ["".join(c) for c in combinations_with_replacement("abcdefghijklmnopqrstuvwxyz", 3)]
for n in (500, 1_000):
    groups, comparisons = group_brute(classes[:n])
    print(f"n = {n:,}: {len(groups):,} groups, {comparisons:,} comparisons")
n = 100_000
print(f"n = {n:,}: up to {n * (n - 1) // 2:,} comparisons")

Output

[['inch', 'chin'], ['rate', 'tear', 'tare'], ['chain', 'china']]
[['aa', 'aa'], ['a']]
[['solo']]
n = 500: 500 groups, 124,750 comparisons
n = 1,000: 1,000 groups, 499,500 comparisons
n = 100,000: up to 4,999,950,000 comparisons

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 groups_brute.py

Doubling the words quadruples the comparisons: n(n − 1)/2 of them, each costing up to the length of a word. At 100,000 words that is about 5 × 10⁹ comparisons. Step through the first example to see each word compared with the groups:

Interactive · step by step Grouping seven words by comparing each with every group Step through the round. Each word is compared with the first word of each group in turn, and joins the first group that has the same letters.
Grouping seven words by comparing each with every group, step 8 of 8. Showing Word read (china, 11 comparisons), Group 1 (inch, chin), Group 2 (rate, tear, tare), Group 3 (chain, china). In focus: Word read.Word readchina, 11 comparisonsGroup 1inch, chinGroup 2rate, tear, tareGroup 3chain, china

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. inch. The round is inch, rate, chin, tear, chain, tare and china. There is no group yet, so inch starts group 1 without a comparison.
  2. rate. rate is compared with inch, the first word of group 1. The letters differ, so rate starts group 2. 1 comparison so far.
  3. chin. chin is compared with inch and has the same letters, so it joins group 1 at the first comparison. 2 so far.
  4. tear. tear differs from inch and matches rate, so it joins group 2 after 2 comparisons. 4 so far.
  5. chain. chain matches neither inch nor rate, so it starts group 3 after 2 comparisons. 6 so far.
  6. tare. tare differs from inch and matches rate, so it joins group 2. 8 comparisons so far.
  7. china. china is compared with inch, rate and chain, and joins group 3 at the third comparison. 11 comparisons in all.
  8. The slowest round. Every new group adds one comparison for every later word. When no two words match, each word is compared with every group before it, n(n − 1)/2 comparisons in all.

What to notice

Two words belong together when something that ignores the order of letters is equal for both. If every word carries that something as a key, finding its group is one lookup in a hash map instead of a comparison with every group. Two keys are in common use for anagrams:

  • A sorted-letters key writes a word’s letters in alphabetical order, so “tear” becomes “aert”. Building it sorts the word, which is quick for short words.
  • A count key lists how many times each of the 26 letters appears in the word. It reads the word once, whatever its length, and then holds 26 numbers.

Checkpoint

Check: Groups of words made of the same letters · Comparing each word with every group · Sorted letters and letter counts as keys

  1. Question 1 of 3 What does the game return for the words ["aa", "a", "aa"]?

    Choose one answer.

    Show the answer: Question 1 of 3

    Answer: [["aa", "aa"], ["a"]]

    Equal letters with equal counts make a group; groups keep their words in typing order, and come in the order of their first words.

  2. Question 2 of 3 A round of 2,000 words has no two words with the same letters. How many comparisons does the brute force make?

    Type a number.

    A hint

    Every word is compared with every group before it, and every word starts a group.

    Show the answer: Question 2 of 3

    Answer: 1999000 comparisons

    0 + 1 + … + 1,999 = 2,000 × 1,999 / 2 = 1,999,000 comparisons, four times the 499,500 the run printed for 1,000 words.

  3. Question 3 of 3 What is the sorted-letters key of "tear"?

    Choose one answer.

    Show the answer: Question 3 of 3

    Answer: aert

    Sorting a word's letters gives the same string for every word made of the same letters, so "rate", "tear" and "tare" all become "aert".

Questions on the word game, its brute force and the two keys follow, beginning with the idea your answers show is weakest.

Practice that adapts to you

Practise this lesson

8 questions about 8 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 8 In which order does the game return its groups?

    Choose one answer.

    Show the answer: Question 1 of 8

    Answer: In the order of their first words

    Each group lists its words in typing order, and the groups come in the order of their first words.

  2. Question 2 of 8 What does the game return for ["dog", "god", "cat", "act", "dog"]?

    Choose one answer.

    Show the answer: Question 2 of 8

    Answer: [["dog", "god", "dog"], ["cat", "act"]]

    Equivalence is "the same letters, each as many times", so dog, god and the repeated dog are one group.

  3. Question 3 of 8 Which round makes the brute force slowest?

    Choose one answer.

    Show the answer: Question 3 of 8

    Answer: One where no two words have the same letters

    With no two words matching, the comparisons add up to n(n − 1)/2, about 5 × 10⁹ at 100,000 words.

  4. Question 4 of 8 In the stepped figure, how many comparisons does the brute force make for the seven words of the first example?

    Type a number.

    A hint

    Add the comparisons of each word, from 0 for inch to 3 for china.

    Show the answer: Question 4 of 8

    Answer: 11 comparisons

    0 for inch, 1 for rate, 1 for chin, 2 for tear, 2 for chain, 2 for tare and 3 for china: 11 in all.

  5. Question 5 of 8 The limits allow 100,000 words. Why can the brute force not meet them?

    Choose one answer.

    Show the answer: Question 5 of 8

    Answer: It can need about 5 × 10⁹ comparisons, each costing up to a word's length

    Each word is compared with every group so far, so the work grows with the square of the number of words.

  6. Question 6 of 8 What does a count key hold for a word?

    Choose one answer.

    Show the answer: Question 6 of 8

    Answer: How many times each of the 26 letters appears in it

    A count key reads the word once, whatever its length, and then holds 26 numbers.

  7. Question 7 of 8 Which of the two keys reads a word only once, whatever its length?

    Choose one answer.

    Show the answer: Question 7 of 8

    Answer: The count key

    Sorting a word is quick for short words, and the count key reads it once and then holds 26 numbers.

  8. Question 8 of 8 Do "aab" and "abb" share a key?

    Choose one answer.

    Show the answer: Question 8 of 8

    Answer: No, neither the sorted-letters key nor the count key

    They are not made of the same letters, each as many times, so a good key must keep them apart.

Grouping in one pass, with the key’s contract Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • A key that is too coarse, and one Python refuses
  • Keys that every language compares by value, in 14 languages
  • Sorted keys against count keys, measured
  • Other equivalences, other keys
  • Variants, edge cases and the common bugs
    • Edge cases and common bugs
    • Variants
  • Practice: group the rotations of each word
    • Group the words that are rotations of each other
  • Interview questions
    • Group 10⁶ words of up to 30 lowercase letters into anagram classes within 2 seconds. Which canonical key do you build, what does each choice cost in time and memory, and would your answer change between Python and C++?
    • A 1,000 × 1,000 grid holds islands of land cells. Count the distinct island shapes, where two islands have the same shape if one can be moved, turned or mirrored onto the other. What key do you give each island, and what does it cost?
    • Sign-ups arrive as email addresses typed by users. The product team wants a warning when someone signs up again with "the same" address. Design the canonical key, and say which normalisations are safe and which can merge two different people.
  • Key takeaways

1 diagram · 6 runnable examples (Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 30 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Terms in this lesson

canonical key
A value computed from an item that every item equivalent to it shares and no other item has, such as a word's letters in sorted order for words made of the same letters.
hashable
Usable as a key of a hash map or a member of a set: the value's hash never changes while it is stored, and two equal values have equal hashes.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.