Skip to main content
4 of 6
update to sort(reverse=True), add O(n) algorithm using Counter
John K.
  • 265
  • 1
  • 6

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter.get(str(i), 0) for i in range(9, -1, -1)))
John K.
  • 265
  • 1
  • 6