Yanıtlar:
Biliyor ve çünkü içinde kodlanabilir bitleri belleğinde ve tek bir yolda yapılabilir (sadece bulun , bu sayı eksik). S=n(n+1) O(log(n))O(logn)S-currentSum
Ancak bu sorun genel olarak (sabit ) çözülebilir : eksik sayılarımız var, hepsini öğrenin. Yerine hesaplama Bu durumda sadece bir özetlemek ait j'st gücünün hesapla toplamını herkes için (ı kabul sayıları eksikse ve girdi sayılardır):k y i x i 1 ≤ j ≤ k x i y i
hesaplayabileceğinizi basitçe, çünkü , , ...S 1 = S - ∑ y i S 2 = ∑ i 2 - ∑ y 2 i
Şimdi eksik numaraları bulmak için tüm bulmak için çözmelisiniz .x i
Hesaplayabilirsiniz:
P 2 = ∑ x i ⋅ x j P k = ∏ x i ( 2 ) , , ..., .
Bunun için hatırlıyorum , , ...P 2 = S 2 1 - S 2
Ancak , ancak benzersiz bir şekilde çarpanlarına ayrılabilir, böylece eksik sayıları bulabilirsiniz. P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ) P
Bunlar benim düşüncelerim değil; okumak bu .
Yukarıdaki yorumdan:
Akışı işlemeden önce, ( bitlerini . ve ikili münhasırdır. Saf olarak, bu zaman alır.X : = ⨁ n i = 1 b i , n ( i ) b ı , n ( i ) I ⊕ O ( n )
Akışı işledikten sonra, kişi sayısını okuduğunda hesaplayın . , akışa dahil olmayan aralığındaki tek sayı olsun . Akışın tamamını okuduktan sonra istenen sonucu verir.X : = x ⊕ b i n ( j ) k, { 1 , . . . n } x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b i n ( i ) ) = b i n ( k ) ⊕ ⨁ i ≠ k
Bu nedenle, alanı kullandık ve genel olarak çalışma süresine sahibiz .
HdM'nin çözümü işe yarıyor. Test etmek için C ++ 'da kodladım. Ben sınırlayamaz value
için biti, ama emin kolayca bit sayısı gerçekte ayarlandığını nasıl yalnızca gösterebilir değilim.
Sahte kod isteyenler için , exclusive veya ( ) ile basit bir işlemi :
El-dalga geçirmez: A hiçbir zaman girişinden daha fazla bit gerektirmez, bu nedenle yukarıdaki hiçbir ara sonuç girişin maksimum bitlerinden daha fazlasını gerektirmez (yani bitleri). değişmeli ve olduğundan, yukarıdakileri genişletir ve akışta bulunan tüm verileri yalnızca tek bir eşleşmeyen değer olan eksik sayı kalır.O ( log 2 n ) ⊕ x ⊕ x = 0
#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;
}