Last Updated: March 29, 2026
Two strings are anagrams if and only if they contain the exact same characters with the exact same frequencies. "listen" and "silent" are anagrams because both have one 'l', one 'i', one 's', one 't', one 'e', and one 'n'. But "hello" and "world" are not, because their character counts differ.
So the real question is: how do we efficiently check whether two strings have identical character frequency distributions? There are a few ways to think about it, from straightforward sorting to direct counting.
1 <= s.length, t.length <= 5 * 10^4 → With n up to 50,000, O(n^2) would mean 2.5 billion operations, which is too slow. O(n log n) and O(n) are both fine.s and t consist of lowercase English letters → Only 26 possible characters. This means a fixed-size array of length 26 is enough to count frequencies, no need for a hash map.The simplest way to check if two strings are anagrams: sort both of them and compare. If the sorted versions are identical, the original strings must contain the same characters in the same quantities, just in a different order.
Think of it like this. If you have two bags of Scrabble tiles and you arrange each bag's tiles in alphabetical order, the two arrangements will be identical if and only if the bags contain the same tiles.
s and t have different lengths, return false immediately.true. Otherwise, return false.Input:
After sorting both strings:
Both sorted strings are identical, so we return true.
Sorting works, but it establishes a full ordering of all characters when we only need to know if the frequencies match. What if we simply counted how many times each character appears?
Instead of sorting, count the frequency of each character in both strings and compare. Two strings are anagrams if and only if every character appears the same number of times in both.
Since the problem guarantees only lowercase English letters (26 characters), we can use a fixed-size array instead of a hash map. Array access is faster than hash map lookups, and the space is constant.
By incrementing for s and decrementing for t, we're computing the difference in character frequencies. If the difference is zero across the board, the frequencies are identical, which means the strings are anagrams.
The single-loop trick (incrementing and decrementing in the same loop) works because both strings have the same length. This saves us from needing two separate loops or two separate frequency arrays.
s and t have different lengths, return false.s, increment the corresponding count.t, decrement the corresponding count.false. Otherwise, return true.This approach is already optimal in Big-O terms. But can we detect a mismatch during the counting phase itself, without the final verification loop?
Instead of using one combined loop, we first count characters in s, then iterate through t and decrement. If any count goes negative during the t pass, we know immediately that t has more of that character than s, so we can return false early without finishing.
This doesn't change the worst-case complexity, but in practice, non-anagram pairs are often caught within the first few characters.
s and t have different lengths, return false.s (increment counts).t. For each character, decrement its count. If any count drops below zero, return false immediately.false, return true.