Поскольку числа (относительно) малы, мы можем просто преобразовать их в строку, пропустить их через фильтр уникальности и вычислить количество элементов. Например в Python:
def nuniqdigits(n):
return len(set(str(n)))
Преобразование в строку является относительно дорогим, мы можем итеративно перечислять цифры следующим образом:
def digits(n):
if n:
while n:
yield n % 10
n //= 10
else:
yield 0
, поэтому мы можем вычислить количество различных цифр как:
def nuniqdigits(n):
return len(set(digits(n)))
Поскольку возможные значения для цифр ограничены, мы можем использовать здесь битовую маску. Например, в Haskell:
import Data.Bits((.|.), popCount, shiftL)
import Data.Word(Word16)
nuniqdigits :: Int -> Int
nuniqdigits n = popCount (foldr (.|.) (0 :: Word16) (map (shiftL 1) (digits n)))
where digits n | n <= 9 = [n]
| otherwise = uncurry (flip (:) . digits) (divMod n 10)
Число n имеет O (log n) цифр, и так как мы делаем итерации по количеству цифр, и все операции являются постоянными в каждой итерации, это выполняется в O (log n) .