উত্তর:
You know , and because could be coded in bits this can be done in memory and in one path (just find , this is missing number).
But this problem could be solved in general case (for constant ): we have missing numbers, find out all of them. In this case instead of calculating just sum of , calculate sum of j'st power of for all (I assumed is missing numbers and is input numbers):
Remember that you can calculate simply, because , , ...
Now for finding missing numbers you should solve to find all .
You can compute:
, , ... , .
For this remember that , , ...
But is coefficients of but could be factored uniquely, so you can find missing numbers.
These are not my thoughts; read this.
From the comment above:
Before processing the stream, allocate bits, in which you write ( is the binary representation of and is pointwise exclusive-or). Naively, this takes time.
Upon processing the stream, whenever one reads a number , compute . Let be the single number from that is not included in the stream. After having read the whole stream, we have
Hence, we used space, and have an overall runtime of .
HdM's solution works. I coded it in C++ to test it. I can't limit the value
to bits, but I'm sure you can easily show how only that number of bits is actually set.
For those that want pseudo code, using a simple operation with exclusive or ():
Hand-wavey proof: A never requires more bits than its input, so it follows that no intermediate result in the above requires more than the maximum bits of the input (so bits). is commutative, and , thus if you expand the above and pair off all data present in the stream you'll be left only with a single un-matched value, the missing number.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
void find_missing( int const * stream, int len );
int main( int argc, char ** argv )
{
if( argc < 2 )
{
cerr << "Syntax: " << argv[0] << " N" << endl;
return 1;
}
int n = atoi( argv[1] );
//construct sequence
vector<int> seq;
for( int i=1; i <= n; ++i )
seq.push_back( i );
//remove a number and remember it
srand( unsigned(time(0)) );
int remove = (rand() % n) + 1;
seq.erase( seq.begin() + (remove - 1) );
cout << "Removed: " << remove << endl;
//give the stream a random order
std::random_shuffle( seq.begin(), seq.end() );
find_missing( &seq[0], int(seq.size()) );
}
//HdM's solution
void find_missing( int const * stream, int len )
{
//create initial value of n sequence xor'ed (n == len+1)
int value = 0;
for( int i=0; i < (len+1); ++i )
value = value ^ (i+1);
//xor all items in stream
for( int i=0; i < len; ++i, ++stream )
value = value ^ *stream;
//what's left is the missing number
cout << "Found: " << value << endl;
}