Réponses:
Vous savez , et parce queS=n(n+1) pourraient être codés enO(log(n))bits cela peut être fait dans lamémoireO(logn)et dans un chemin (il suffit de trouverS-currentSum, c'est le nombre manquant).
Mais ce problème pourrait être résolu dans le cas général (pour constant ): nous avons k nombres manquants, découvrez-les tous. Dans ce cas, au lieu de calculer simplement la somme de y i , calculez la somme de la puissance j'st de x i pour tous les 1 ≤ j ≤ k (j'ai supposé que x i est des nombres manquants et y i est des nombres en entrée):
Rappelez -vous que vous pouvez calculer simplement, car S 1 = S - ∑ y i , S 2 = ∑ i 2 - ∑ y 2 i , ...
Maintenant, pour trouver les nombres manquants, vous devez résoudre pour trouver tous les x i .
Vous pouvez calculer:
, P 2 = ∑ x i ⋅ x j , ..., P k = ∏ x i ( 2 ) .
Pour cela rappelez-vous que , P 2 = S 2 1 - S 2 , ...
Mais est des coefficients de P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ) mais P pourrait être factorisé de manière unique, de sorte que vous pouvez trouver les nombres manquants.
Ce ne sont pas mes pensées; lisez ceci .
Du commentaire ci-dessus:
Avant de traiter le flux, bits, dans lequel vous écrivez x : = ⨁ n i = 1 b i n ( i ) ( b i n ( i ) est la représentation binaire de i et ⊕ est point par point exclusif- ou). Naïvement, cela prend du temps O ( n ) .
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 .
La solution de HdM fonctionne. Je l'ai codé en C ++ pour le tester. Je ne peux pas limiter le value
à bits, mais je suis sûr que vous pouvez facilement montrer comment seul ce nombre de bits est réellement défini.
Pour ceux qui veulent du pseudo code, en utilisant un simple fonctionnement exclusif ou ():
Preuve ondulée à la main: 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;
}