Respuestas:
Sabes , y porqueS=n(n+1) podría codificarse enbitsO(log(n))esto se puede hacer en lamemoriaO(logn)y en una ruta (solo encuentreS-currentSum, este es el número que falta).
Pero este problema podría resolverse en un caso general (para constante ): tenemos k números que faltan, descúbrelos todos. En este caso, en lugar de calcular solo la suma de y i , calcule la suma de j'st potencia de x i para todo 1 ≤ j ≤ k (supuse x faltan números e y i son números de entrada):
Recuerde que puede calcular simplemente, porque S 1 = S - ∑ y i , S 2 = ∑ i 2 - ∑ y 2 i , ...
Ahora, para encontrar números que faltan, debes resolver para encontrar todo x i .
Puedes calcular:
, P 2 = ∑ x i ⋅ x j , ..., P k = ∏ x ( 2 ) .
Para esto recuerde que , P 2 = S 2 1 - S 2 , ...
Pero son coeficientes de P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ), pero P podría factorizarse únicamente, por lo que puede encontrar los números que faltan.
Estos no son mis pensamientos; leer este .
Del comentario anterior:
Antes de procesar el flujo, asigne bits, en el que escriba x : = ⨁ n i = 1 b i n ( i ) ( b i n ( i ) es la representación binaria de i y ⊕ es exclusivo de pointwise- o). Ingenuamente, esto lleva O ( n ) tiempo.
Al procesar la secuencia, cada vez que uno lea un número , calcule x : = x ⊕ b i n ( j ) . Deje que k es el número único de { 1 , . . . n } que no está incluido en la secuencia. Después de haber leído todo el flujo, tenemos x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b produciendo el resultado deseado.
Por lo tanto, utilizamos el espacio y tenemos un tiempo de ejecución general de O ( n ) .
La solución de HdM funciona. Lo codifiqué en C ++ para probarlo. No puedo limitar elvalue
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;
}