Multinomials with inverse factorials
Time O(n + log p) Space O(n)fact and invFact up to the longest word. For each word multiply by fact[L] and invFact[count] for each letter.
s = "too hot"counts(map)
result(vars)
Step 1/3"too": 3 letters give 3! = 6 orders, but the two o's can swap without change, so divide by 2: 3 (too, oto, oot).
class Solution {
private static final long P = 1_000_000_007L;
public int countAnagrams(String s) {
int n = s.length();
long[] fact = new long[n + 1], inv = new long[n + 1];
fact[0] = 1;
for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % P;
inv[n] = power(fact[n], P - 2);
for (int i = n; i > 0; i--) inv[i - 1] = inv[i] * i % P;
long result = 1;
for (String w : s.split(" ")) {
int[] count = new int[26];
for (char c : w.toCharArray()) count[c - 'a']++;
result = result * fact[w.length()] % P;
for (int c : count) result = result * inv[c] % P;
}
return (int) result;
}
private long power(long b, long e) {
long r = 1;
b %= P;
while (e > 0) {
if ((e & 1) == 1) r = r * b % P;
b = b * b % P;
e >>= 1;
}
return r;
}
}Verdict: Each word costs O(L + 26).