• ↑↓ pour naviguer
  • pour ouvrir
  • pour sélectionner
  • ⌘ ⌥ ↵ pour ouvrir dans un panneau
  • ←→ pour naviguer
  • esc pour rejeter
⌘ '
raccourcis clavier

Formal Definition

Anagram detection determines whether two strings are permutations of each other — that is, whether they contain the same characters with the same frequencies. The hash-based approach builds frequency structures for both strings and compares them. Anagrams produce identical frequency maps.

are_anagrams(S1,S2)    c,freqS1(c)=freqS2(c)\text{are\_anagrams}(S_1, S_2) \iff \forall c, \text{freq}_{S_1}(c) = \text{freq}_{S_2}(c)

Explanation

Two strings are anagrams if one can be rearranged to form the other. The simplest correct approach is to count character frequencies for both strings and compare. This elegantly demonstrates the two-phase hashing pattern applied to two inputs simultaneously — Phase 1 runs twice (once per string), then Phase 2 compares the two structures.

How It Works

  1. Build frequency array/map for string 1 (freq1)
  2. Build frequency array/map for string 2 (freq2)
  3. For arrays: compare element by element — all 26 slots must match
  4. For maps: compare key-value pairs — all keys in one must exist in the other with the same values
  5. If all counts match, the strings are anagrams

Mathematical Formulation

For strings S1S_1 and S2S_2 over alphabet Σ\Sigma:

Anagram(S1,S2)    cΣ,count(S1,c)=count(S2,c)\text{Anagram}(S_1, S_2) \iff \forall c \in \Sigma, \text{count}(S_1, c) = \text{count}(S_2, c)

Anagram(S1,S2)    cΣcount(S1,c)count(S2,c)=0\text{Anagram}(S_1, S_2) \iff \sum_{c \in \Sigma} |\text{count}(S_1, c) - \text{count}(S_2, c)| = 0

Visual Explanation

digraph anagram_detection {
  rankdir=TB
  node [shape=box style=filled fillcolor="#f0f4ff" fontname="Helvetica"]
 
  S1 [label="String 1:\n'listen'"]
  S2 [label="String 2:\n'silent'"]
  P1_S1 [label="Phase 1\nBuild freq1"]
  P1_S2 [label="Phase 1\nBuild freq2"]
  F1 [label="freq1:\ne:1, i:1, l:1\nn:1, s:1, t:1"]
  F2 [label="freq2:\ne:1, i:1, l:1\nn:1, s:1, t:1"]
  COMPARE [label="Compare\nfreq1 == freq2?" shape=diamond]
  YES [label="Anagram!" fillcolor="#d4edda]
  NO [label="Not Anagram" fillcolor="#ffe5cc"]
 
  S1 -> P1_S1
  S2 -> P1_S2
  P1_S1 -> F1
  P1_S2 -> F2
  F1 -> COMPARE
  F2 -> COMPARE
  COMPARE -> YES [label="yes"]
  COMPARE -> NO [label="no"]
}

Semantic Network

semantic_anagram THIS Anagram Detection PRE1 Hashing Retrieval Phase THIS--PRE1 built from PRE2 Two-Phase Hashing THIS--PRE2 built from PRE3 Frequency Array THIS--PRE3 built from OUT1 Character Hashing Use Cases THIS--OUT1 builds into CON1 Most Frequent Character THIS--CON1 contrasts with CON2 First Non-Repeating Character THIS--CON2 contrasts with REL1 Unordered Map Frequency THIS--REL1 related REL2 Known Range Assumption THIS--REL2 related

Key Properties

  • O(n + m) time where n and m are the lengths of the two strings
  • O(|Σ|) space for arrays (26 slots), O(k) for maps (k distinct characters in both strings)
  • Two structures must be compared — doubles the Phase 1 work
  • Early exit possible: if lengths differ, they cannot be anagrams (check before building)
  • Sorting both strings and comparing is also correct but O(n log n) — hashing is faster

Connections

Edge Cases & Gotchas

  • Different lengths: immediately return false — no need to build structures
  • Empty strings: two empty strings are anagrams (both have zero length and empty frequency maps)
  • Case sensitivity: “Listen” and “Silent” are not anagrams by default — convert to same case first if needed
  • Unicode characters: arrays cannot handle this — must use hash maps
  • Whitespace and punctuation: the problem typically specifies whether to ignore these
  • Sorting approach (O(n log n)) is simpler to code but slower — hashing is the interview-optimized answer