Respostas:
Você sabe e porqueS=n(n+1) pode ser codificado embitsO(log(n)),isso pode ser feito namemóriaO(logn)e em um caminho (basta encontrarS-currentSum, esse número está faltando).
Mas esse problema pode ser resolvido no caso geral (para a constante ): temos k números ausentes, descubra todos eles. Nesse caso, em vez de calcular apenas a soma de y i , calcule a soma da j'st de x i para todos os 1 ≤ j ≤ k (assumi que x i está faltando números e y i é um número de entrada):
Lembre-se que você pode calcular simplesmente, porque S 1 = S - Σ y i , S 2 = Σ i 2 - Σ Y 2 i , ...
Agora, para encontrar números ausentes, você deve resolver para encontrar todos os x i .
Você pode calcular:
, P 2 = ∑ x i ⋅ x j , ..., P k = ∏ x i ( 2 ) .
Para isso, lembre-se de que , P 2 = S 2 1 - S 2 ...
Mas é coeficiente de P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ), mas P pode ser fatorado exclusivamente, para que você possa encontrar números ausentes.
Estes não são meus pensamentos; leia isso .
Do comentário acima:
Antes de processamento da corrente, alocar bits, onde escrever x : = ⨁ n i = 1 b i n ( i ) ( b i n ( i ) é a representação binária de i e ⊕ é pontual exclusive- ou). Ingenuamente, isso leva tempo O ( n ) .
Ao processar o fluxo, sempre que alguém ler um número , calcule x : = x ⊕ b i n ( j ) . Vamos k ser o número único de { 1 , . . . n } que não está incluído no fluxo. Depois de ler todo o fluxo, temos x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b obtendo-se o resultado desejado.
Portanto, usamos espaço e temos um tempo de execução geral de O ( n ) .
value
#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;
}