Вы можете вести подсчет количества ходов для каждого персонажа и наращивать результат по мере продвижения. Это невозможно сделать лучше, чем O (n), поскольку, не глядя на каждый символ в строке, вы не сможете узнать, сколько в нем каждого символа.
Я написал некоторый код на Python с несколькими простыми модульными тестами. Код тщательно избегает больших промежуточных значений, когда результат будет небольшим (на самом деле, переменная result
никогда не превышает len (s), умноженный на конечный результат). Если вы собираетесь кодировать это на другом языке, например, C, то вы можете использовать массив размером 256, а не defaultdict.
Если вам нужен точный результат, тогда я не думаю, что вы можете добиться большего успеха, чем этот.
from collections import defaultdict
def permutations(s):
seen = defaultdict(int)
for c in s:
seen[c] += 1
result = 1
n = 0
for k, count in seen.iteritems():
for j in xrange(count):
n += 1
result *= n
result //= j + 1
return result
test_cases = [
('abc', 6),
('aab', 3),
('abcd', 24),
('aabb', 6),
('aaaaa', 1),
('a', 1)]
for s, want in test_cases:
got = permutations(s)
if got != want:
print 'permutations(%s) = %s want %s' % (s, got, want)