Risposte:
Sai e perché potrebbe essere codificato in bit questo può essere fatto nella memoria O (\ log n) e in un percorso (basta trovare S - \ mathrm {currentSum} , questo è il numero mancante). S=n(n+1) O(log(n))O(logn)S-currentSum
Ma questo problema potrebbe essere risolto nel caso generale (per costante ): abbiamo numeri mancanti, scoprili tutti. In questo caso invece di calcolare solo la somma di , calcola la somma della j'st potenza di per tutti (ho assunto che manchi numeri mancanti e sia numeri di input):
Ricorda che puoi calcolare semplicemente, perché , , ...
Ora per trovare i numeri mancanti dovresti risolvere per trovare tutti .
Puoi calcolare:
, , ..., .
Per questo ricorda che , , ...
Ma è coefficienti di ma potrebbe essere considerato in modo univoco, quindi puoi trovare i numeri mancanti.
Questi non sono i miei pensieri; Leggere questo .
Dal commento sopra:
Prima di elaborare il flusso, allocare bit, in cui si scrive ( è il la rappresentazione binaria di e è in senso esclusivo o). Ingenuamente, ciò richiede tempo.
Dopo aver elaborato il flusso, ogni volta che si legge un numero , calcolare . Sia il numero singolo di che non è incluso nello stream. Dopo aver letto l'intero flusso, abbiamo producendo il risultato desiderato.
Quindi, abbiamo usato lo spazio e abbiamo un tempo di esecuzione complessivo di .
La soluzione di HdM funziona. L'ho codificato in C ++ per testarlo. Non posso limitare i bit value
a , ma sono sicuro che puoi facilmente mostrare come è impostato solo quel numero di bit.
Per coloro che desiderano uno pseudo codice, utilizzare una semplice operazione di con esclusivo o ( ⊕ ):
Hand-wavey proof: A non richiede mai più bit del suo input, quindi ne consegue che nessun risultato intermedio sopra richiede più dei bit massimi dell'input (quindi O ( log 2 n ) bit). ⊕ è commutativo e x ⊕ x = 0 , quindi se si espande quanto sopra e si accoppiano tutti i dati presenti nello stream, si rimarrà solo con un singolo valore non corrispondente, il numero mancante.
#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;
}