Count Anagrams

Count distinct anagrams of every space-separated word, multiplied together modulo 1e9+7.

Hard
Time O(N + L) Space O(L)
LeetCode
6 min read
hash-map math combinatorics modular

Problem#

A “good” string is any permutation of s (space-separated words) such that each word is replaced by an anagram of itself (spaces stay in place). Return the count of good strings modulo 10^9 + 7.

Examples#

  • s = "too hot"18 (3!/2! * 3! = 18).
  • s = "aa"1.

Constraints#

  • 1 <= s.length <= 10^5.

Hints#

Hint
For each word, anagrams = L! / prod(count[c]!). Multiply across words.

Approach#

Precompute factorials and modular inverses up to N. For each word, multiply L! by the modular inverse of prod(count[c]!). Accumulate across all words.

Solution#

Count Anagrams
class Solution {
static const int MOD = 1'000'000'007;
long long power(long long a, long long b, long long mod) {
long long r = 1; a %= mod;
while (b) { if (b & 1) r = r * a % mod; a = a * a % mod; b >>= 1; }
return r;
}
public:
int countAnagrams(string s) {
int n = s.size();
vector<long long> fact(n + 1, 1);
for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i % MOD;
long long ans = 1;
int i = 0;
while (i < n) {
int j = i;
while (j < n && s[j] != ' ') ++j;
int L = j - i;
int cnt[26] = {0};
for (int k = i; k < j; ++k) ++cnt[s[k] - 'a'];
long long word = fact[L];
for (int c = 0; c < 26; ++c) if (cnt[c] > 1)
word = word * power(fact[cnt[c]], MOD - 2, MOD) % MOD;
ans = ans * word % MOD;
i = j + 1;
}
return static_cast<int>(ans);
}
};

Editorial#

Each word’s anagram count is the multinomial L! / prod(cnt[c]!). Working under a prime modulus, division becomes multiplication by Fermat’s little theorem inverse. Words are independent, so total count multiplies across words. Precomputed factorials keep each word’s work O(L + 26 log MOD).

Complexity#

  • Time: O(N + 26 log MOD) total.
  • Space: O(N) for factorials.

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.