Skip to content
Hash map: count and look up

Lesson 4.3

Check anagrams

7 min · 8 steps

  1. Step 1 of 8 · Explanation

    Two strings are anagrams when every letter appears the same number of times in both. The order doesn't matter.

    The method: check the lengths first. Then count up each letter in a, and count down each letter in b. If a letter in b already has a count of 0, it's not an anagram.

  2. Step 2 of 8 · Predict the result

    Same code. What does it return for "aab" and "abb"?

    function solution(a, b) {  if (a.length !== b.length) {    return false  }  const counts = new Map()  for (const ch of a) {    counts.set(ch, (counts.get(ch) || 0) + 1)  }  for (const ch of b) {    if (!counts.get(ch)) {      return false    }    counts.set(ch, counts.get(ch) - 1)  }  return true}
    1. false
    2. true
  3. Step 3 of 8 · Predict the result

    This version skips the length check. What does it return for "abc" and "ab"?

    function solution(a, b) {  const counts = new Map()  for (const ch of a) {    counts.set(ch, (counts.get(ch) || 0) + 1)  }  for (const ch of b) {    if (!counts.get(ch)) {      return false    }    counts.set(ch, counts.get(ch) - 1)  }  return true}
    1. true
    2. false
  4. Step 4 of 8 · Pick the approach

    Which check proves that two strings are anagrams?

    1. Same length, and every letter has the same count
    2. Every letter of a appears in b
    3. Same length and the same set of letters
    4. The same first and last letter
  5. Step 5 of 8 · Arrange the code

    Build a function that returns true if a and b are anagrams. Count up from a, count down from b, then make sure every count is back to 0. Two lines don't belong.

    const counts = new Map()for (const c of counts.values()) {for (const ch of b) counts.set(ch, (counts.get(ch) || 0) + 1)if (a.length !== b.length) return false}if (c !== 0) return falsefor (const ch of b) counts.set(ch, (counts.get(ch) || 0) - 1)return true}function solution(a, b) {for (const ch of a) counts.set(ch, (counts.get(ch) || 0) + 1)if (c === 0) return false
  6. Step 6 of 8 · Find the bug

    This anagram check uses a plain object. For "ab" and "ba" this code returns false, but it should be true. Tap the wrong line.

    function solution(a, b) {  if (a.length !== b.length) return false  const counts = {}  for (const ch of a) counts[ch]++  for (const ch of b) counts[ch]--  return Object.values(counts).every((c) => c === 0)}
  7. Step 7 of 8 · Write the code

    solution(note, letters)

    Return true if note can be built from the letters in letters. Each letter in letters can only be used once.
    Constraints: 0 ≤ note.length, letters.length ≤ 10⁵, lowercase letters only.

    function solution(note, letters) {  // "aab", "baa" -> true  // "aa", "ab" -> false }
  8. Step 8 of 8 · Recap

    • An anagram means every letter has the same count, not just the same letters.
    • Check the length first. Without it, leftover letters in the longer string slip through.
    • Count up from one string, count down from the other.

    Pattern card

    Count up, count down
    When to use it: When two collections must hold the same items in any order. Anagrams, building from letters, or comparing inventories.
    if (a.length !== b.length) return falsefor (const ch of a) counts.set(ch, (counts.get(ch) || 0) + 1)for (const ch of b) {  if (!counts.get(ch)) return false  counts.set(ch, counts.get(ch) - 1)}return true