Valid Anagram

Valid Anagram

Given two strings, determine if one is an anagram of the other. Two strings are anagrams if they contain the same characters with the same frequencies, just in a different order.

isAnagram(s, t)

Input format: two space-separated words on one line.

Examples

isAnagram("listen", "silent")  // → true
isAnagram("hello", "world")    // → false
isAnagram("abc", "bca")        // → true
isAnagram("a", "a")            // → true

Walkthrough

Thinking it through

Two strings are anagrams if they're made of the same characters, the same number of times each, just rearranged. Order doesn't matter at all — it's purely about whether the two strings have matching character counts.

A first idea that's tempting but expensive

You could sort both strings and compare the results. That works, but sorting costs O(n log n), and you'd pay it twice. There's no need to impose an order just to compare frequencies — this is a counting problem, not an ordering one.

Reframing as a counting problem

If two strings are anagrams, every character appears the same number of times in both. So build a tally of character counts for one string, then check the other string matches that tally exactly.

Building the approach

  1. Check the lengths first. If they differ, the strings can't be anagrams — free early exit.
  2. Walk the first string once, counting each character into a hash map.
  3. Walk the second string, decrementing that same map instead of building a second one. You build one map and consume it while scanning the other string.
  4. If a count would drop below zero, the second string has more of that character than the first — not anagrams, stop immediately.
  5. If you get through the second string with no count going negative, and the lengths matched, every character was used exactly as many times as counted — they're anagrams.

Why decrementing (not a second map) is the elegant move

Comparing two separately-built frequency maps means checking every key in both. Decrementing a single map while consuming the second string collapses "build and compare" into one pass, with an early exit the moment something doesn't fit — like filling a bucket, then draining it, and checking you never try to drain more than exists.

Why this generalizes

Any problem comparing the multiset of two collections — regardless of order — reduces to counting. Tallying frequencies is usually cheaper and more direct than sorting, especially when you can consume one map while scanning the second for an early exit.

main.py
Console
Press Run to execute your code, or Submit to test and complete this problem.