views:

241

answers:

3

Possible Duplicate:
Quickest way to find missing number in an array of numbers

Input: unsorted array A[1,..,n] which contains all but one of the integers in the range 0,..,n

The problem is to determine the missing integer in O(n) time. Each element of A is represented in binary, and the only operation available is the function bit(i, j), which returns the value of the jth bit of A[i] and takes constant time.

Any ideas? I think some sort of divide-and-conquer algorithm would be proper, but I can't think of what exactly I should do. Thanks in advance!

+8  A: 

It's a mathematical property that the sum of the numbers between 1 and n where n is n(n+1)/2. You can see this for 10:

  1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
= (1+10) + (2+9) + (3+8) +(4+7) + (5+6)
= 11 + 11 + 11 + 11 + 11
= 55

So, by extension, is the sum of the numbers from 0 thru n since you're just adding 0 to it. So what you do is add up all the numbers and maintain a count, then use that formula to figure out the missing one.

So, something like:

count = 0
sum = 0
foreach num in list:
    sum = sum + num
    count = count + 1
missing = count * (count+1) / 2 - sum

Getting the number with bit(i,j) is tricky so you'll have to extract the bits individually and turn them into actual numbers for summing.

paxdiablo
This reads all n log n bits of A, so it takes n log n time.
Reid Barton
@Reid: no, it's not n log n at all. You can't use n for both the number of bits _and_ the number of integers. The number of bits in an integer is _constant_ so it's effectively `O(32n)` (for a 32-bit number) which is exactly the same as `O(n)`.
paxdiablo
I'm pretty sure when the OP writes "integer", they mean "integer", not "integer less than 2^32". Otherwise, there are only finitely many possible inputs, so it doesn't make sense to talk about asymptotic runtime at all. Obviously the length of an actual mathematical integer in bits is not constant.
Reid Barton
paxdiablo
A: 

It's a trick question then, since using the bit method would only require that you cycle each bit for each number, meaning it would automatically become O(n*j) where j is the number of bits representing n.

I think paxdiablo's got it, assuming you're allowed a solution which doesn't use the bit method.

Neil
Neil, that would still be technically `O(n)` since `j` is a constant.
paxdiablo
j is constant in practice because the length of an integer or long is always the same, however the significant digits of j increments by one with n*2 where n > 0. More like O(log n).
Neil
+7  A: 

You could use XOR operator as its faster than addition. Since you have access to each bit you will be doing a bitwise XOR here. The principle to be used here is (A XOR B XOR A ) = B

eg: (1 XOR 2 XOR 3) XOR (1 XOR 2) = 3

for i=0 to n
{
Total=Total XOR i
}

foreach element in A
{
Total=Total XOR element
}
Mulki
Actually, that's pretty nifty, +1. You can't be _sure_ that XOR will be faster than addition but it's a neat modification to the two-of-most/one-of-one (e.g., `91 91 82 82 73 64 64 55 55`) variation that uses XOR to find the singleton.
paxdiablo
Xor will never be slower than Addition... Why : In addition there is a carryover bit which requires a full adder adding one step...It is eliminated using parallel adders in modern architecture which has almost the same performance(xor uses 1 gate lesser on this operation)
Mulki
There is an O(1) formula for XOR of 1 to n. http://stackoverflow.com/questions/3932346/direct-formula-for-summing-xor. XOR also avoids overflow issues.
Moron