Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    Valid Anagram

    Given two strings s and t, return true if t is an anagram of s, and false otherwise.

    Example 1

    Input: s = "anagram", t = "nagaram"

    Output: true

    Example 2

    Input: s = "rat", t = "car"

    Output: false

    Constraints

    • 1 <= s.length, t.length <= 5 * 10^4
    • s and t consist of lowercase English letters.
    Follow-up: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?
    View original on LeetCode ↗

    Two strings are anagrams exactly when they contain the same letters the same number of times. That’s a statement about counts, not order, so the fastest way to check it avoids arranging the letters at all — it just tallies them.

    Sort and Compare

    Time O(n log n)Space O(n)

    If s and t are anagrams, sorting both produces identical strings. If they aren’t, sorting won’t magically make them equal.

    class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
    return sorted(s) == sorted(t)

    Correct and simple, but sorted() allocates new lists and costs O(n log n) — more work than the comparison actually requires, since it also implicitly checks length equality and character multiplicity together.

    Character Counting

    OptimalTime O(n)Space O(1)

    Count every character in s into a hash map, then walk t decrementing those same counts. If a character in t isn’t in the map, or a count ever goes negative, they can’t be anagrams. If every count lands back at zero, they are.

    class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
    if len(s) != len(t):
    return False
    counts = {}
    for ch in s:
    counts[ch] = counts.get(ch, 0) + 1
    for ch in t:
    if ch not in counts:
    return False
    counts[ch] -= 1
    if counts[ch] == 0:
    del counts[ch]
    return len(counts) == 0

    Tracing s = "anagram", t = "nagaram" — count the letters of s first, then spend those counts on t. Watch the map: a count that reaches zero is deleted, so an empty map at the end means the two strings had exactly the same letters.

    Pass 1 · counting s

    s count
    anagram
    t spend
    nagaram

    Count map

    a×0g×0m×0n×0r×0
    Return—
    1 / 15
    currentseendiscardedresult

    Both strings are 7 letters, so lengths already match — only letter counts can still differ. Pass 1 counts every letter of s.

    Correctness: the map after the first pass records exactly how many of each character s needs. The second pass spends those counts one by one; if t ever asks for a character that isn’t available, the strings aren’t anagrams. Since len(s) == len(t) is checked up front, ending with every count spent to zero proves the multisets match exactly.

    Complexity: two linear passes over strings of length n — O(n) time. With lowercase English letters the map holds at most 26 entries — O(1) space (for the Unicode follow-up, the map would instead hold up to n distinct code points, making space O(n) — the algorithm itself needs no other change since a hash map works for any hashable character set).

    More Arrays & Hashing practice