7

Is is possible to count the distinct digits in a number in constant time O(1)?

Suppose n=1519 output should be 3 as there are 3 distinct digits(1,5,9).

I have done it in O(N) time but anyone knows how to find it in O(1) time?

timrau
  • 22,578
  • 4
  • 51
  • 64
Ronin
  • 2,027
  • 8
  • 32
  • 39

2 Answers2

6

I assume N is the number of digits of n. If the size of n is unlimited, it can't be done in general in O(1) time.

Consider the number n=11111...111, with 2 trillion digits. If I switch one of the digits from a 1 to a 2, there is no way to discover this without in some way looking at every single digit. Thus processing a number with 2 trillion digits must take (of the order of) 2 trillion operations at least, and in general, a number with N digits must take (of the order of) N operations at least.

However, for almost all numbers, the simple O(N) algorithm finishes very quickly because you can just stop as soon as you get to 10 distinct digits. Almost all numbers of sufficient length will have all 10 digits: e.g. the probability of not terminating with the answer '10' after looking at the first 100 digits is about 0.00027, and after the first 1000 digits it's about 1.7e-45. But unfortunately, there are some oddities which make the worst case O(N).

Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127
  • If the given number fits in the underlying machine word, you have a trivial O(1) algorithm; namely look the answer up in a lookup table as suggested (tongue in cheek) by Jon Skeet. For general sized N, my point remains I think. – Simon Nickerson Mar 12 '13 at 21:06
  • I'm sorry, I don't get your point. Whatever the word size is, it will be some fixed finite size. So the big-Oh performance of any algorithm that has to deal with arbitrary-sized data is going to be independent of the size of the word. Doing arithmetic on the words doesn't help, even if such operations can be done in O(1) per-word, because the number of words required to express the number n is itself O(N). – Simon Nickerson Mar 13 '13 at 08:25
2

After seeing that someone really posted a serious answer to this question, I'd rather repeat my own cheat here, which is a special case of the answer described by @SimonNickerson:

O(1) is not possible, unless you are on radix 2, because that way, every number other than 0 has both 1 and 0, and thus my "solution" works not only for integers...

EDIT

How about 2^k - 1? Isn't that all 1s?

Drat! True... I should have known that when something seems so easy, it is flawed somehow... If I got the all 0 case covered, I should have covered the all 1 case too.

Luckily this case can be tested quite quickly (if addition and bitwise AND are considered an O(1) operation): if x is the number to be tested, compute y this way: y=(x+1) AND x. If y=0, then x=2^k - 1. because this is the only case when all the bits needed to be flipped by the addition. Of course, this is quite a bit flawed, as with bit lengths exceeding the bus width, the bitwise operators are not O(1) anymore, but rather O(N).

At the same time, I think it can be brought down to O(logN), by breaking the number into bus width size chunks, and AND-ing together the neighboring ones, repeating until only one is left: if there were no 0s in the number tested, the last one will be full 1s too...

EDIT2: I was wrong... This is still O(N).

ppeterka
  • 20,583
  • 6
  • 63
  • 78
  • 2
    How about 2^k - 1? Isn't that all 1s? – Simon Nickerson Mar 13 '13 at 20:20
  • Drat! True... I should have known that when something seems so easy, it is flawed somehow... If I got the all 0 case covered, I should have covered the all 1 case too. Luckily this case can be tested quite quickly (if addition and bitwise AND are considered an O(1) operation): if x is the number to be tested, compute y this way: `y=(x+1) AND x`. If `y=0`, then `x=2^k - 1`. because this is the only case when all the bits needed to be flipped. Of course, this is quite a bit flawed, as with bit lengths exceeding the bus width, the bitwise operators are not O(1) anymore, but rather O(N)... – ppeterka Mar 13 '13 at 20:46