Reputation: 55
i am trying to solve a question that provides a string as input and gives the number of anagrams possible as output. this can be solved using dictionaries but i could only think in terms of for loops and string indices.
count = 0
for i in range(1,len(s)):
for j in range(0,len(s)):
for k in range(j+1,len(s)):
if(k+i>len(s)):
continue
# print(list(s[j:j+i]),list(s[k:k+i]),j,j+i,k,k+i)
if(sorted(list(s[j:j+i]))==sorted(list(s[k:k+i]))):
count +=1
return count
i have coded this far and tried for optimization with k+i. can someone tell me other techniques to optimize the code without losing the logic. the code keeps getting terminated due to time-out for larger strings.should i replace sorted
function with something else.
Upvotes: 0
Views: 117
Reputation: 3161
The number of anagrams if each letter was unique would be n!
with n
as the length of the string (e.g. law has 3!=6
). If there a given letter is repeated, say, twice (e.g. wall
), then you have twice as many answers as you should (since things like w-(second l)-(first l)-a
are actually indistinguishable from things like w-(first l)-(second l)-a
). It turns out that if a letter is repeated k
times (k
is 2 for the letter "l"
in wall
), n!
overcounts by a factor of k!
. This is true for each repeated letter.
So to get the number of anagrams, you can do:
letter_counts = get_letter_counts(s) #returns something like [1, 1, 2] when given wall, since there is one w, one a, two ls
n_anagrams = factorial(len(s))
#account for overcounts
for letter_count in letter_counts:
n_anagrams /= factorial(letter_count)
return n_anagrams
Implementing factorial
and get_letter_counts
left as an excercise for the reader :-) . Note: Be careful to consider that repeated letters can show up more than once, and not always next to each other. Ex: "aardvark" should return a count of 3 for the "a"s, 2 for the "r"s, and 1 for everything else.
Upvotes: 2