Here’s my solution in Python using the Counter
class. I build a valid string by drawing from the unique letters of the input string, one of each kind at a time, until the counter class is either all zeros (the input is even and I used all letters), or only the most frequent letter remains. If there is only one of the latter, I can add it to the end of the new string and we are good to go. However, if there is more than one remaining “highest-frequency” letter, then I am forced to create a duplicate string.
Building the counter at the top is O(n)
. The while loop might run up to k
times, where k
is the frequency of the most common letter. Therefore the time complexity of the while loop is k*something
, where something
is the complexity of what happens inside the loop. Since each line inside the loop is no worse than O(n)
then the loop itself is O(n)
(dropping some constant). Time complexity overall is then O(n) + kO(n)
or simply O(n)
.
from typing import Counter
def reorganize_string(s: str) -> str:
# WRITE YOUR BRILLIANT CODE HERE
counts = Counter(s)
res = []
while len(counts) > 1: # loop to draw all letters from the counter
letters = list(counts) # we could do this only when len(counts) changes
res.append(''.join(letters))
counts.subtract(letters) # decrease counts by one
counts += Counter() # remove zero-count entries
res = ''.join(res + list(counts))
# algomoster's Python doesn't like 'counts.total()' :-(
# return '' if counts.total() > 1 else res
# hack for algomonster's python
if not counts:
return res
most_common = counts.most_common(1)[0]
most_common_letter = most_common[0]
remaining_count = most_common[1]
return '' if remaining_count > 1 else res