Skip to content

242. Valid Anagram

On LeetCode ->

Reformulated question

Given two strings s and t, decide whether they contain exactly the same characters with the same frequencies, possibly in different orders.

Example:

s="anagram", t="nagaram" -> True
s="rat", t="car" -> False

Key trick

Use character frequency counts.

  • If lengths differ, return False immediately.
  • Then compare counts of each character in both strings.

Trap

Common mistakes:

  • Forgetting the length check.
  • Checking only that every character exists, but not its count.
  • Sorting works, but it is slower than counting for this problem.

Why is this question interesting?

It tests whether you see that order does not matter, only frequencies do.

  • It is a simple hash map counting problem.
  • It also opens the Unicode follow-up naturally.

Solve the problem with idiomatic python

from collections import Counter

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        # Different sizes cannot be anagrams.
        if len(s) != len(t):
            return False

        # Same frequency table means same multiset of characters.
        return Counter(s) == Counter(t)

Alternative without library:

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        # Different sizes cannot be anagrams.
        if len(s) != len(t):
            return False

        counts = {}

        # Count characters from s.
        for ch in s:
            counts[ch] = counts.get(ch, 0) + 1

        # Remove using t; fail if a character is missing/overused.
        for ch in t:
            if counts.get(ch, 0) == 0:
                return False
            counts[ch] -= 1

        return True

Pytest test

import pytest

@pytest.mark.parametrize(
    ("s", "t", "expected"),
    [
        ("anagram", "nagaram", True),
        ("rat", "car", False),
        ("a", "a", True),
        ("ab", "ba", True),
        ("ab", "aa", False),
        ("", "", True),
        ("aacc", "ccac", False),
        ("listen", "silent", True),
        ("hello", "bello", False),
    ],
)
def test_is_anagram(s, t, expected):
    assert Solution().isAnagram(s, t) is expected

Comment my solution

Your solution is correct and efficient.

  • Good:

    • Early length check.
    • Linear time.
    • Handles overuse of a character correctly.
  • Small simplification:

    • return Counter(s) == Counter(t) is shorter and equally clear here.
  • Test issue:

    • Your test misses edge cases.
    • ("", "") is useful in general, but LeetCode here guarantees length at least 1.
from collections import Counter
import pytest

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t):
            return False
        counts = Counter(s)
        for c in t:
            if counts[c] < 1:
                return False
            counts[c] -=1
        return True


@pytest.mark.parametrize(
    ("s", "t", "is_anagram"),
    [
        ("anagram", "nagaram", True),
        ("rat", "car", False)
    ]
)
def test_isAnagram(s, t, is_anagram):
    assert Solution().isAnagram(s,t) == is_anagram