Ответы:
Вы знаете , и потому чтоS=n(n+1) может быть закодирована вO(журнал(п))биты это может быть сделано вO(журналN)памяти и в одном пути (просто найтиS-сутгентСум, это отсутствует число).
Но эту проблему можно решить в общем случае (для константы ): у нас есть k пропущенных чисел, выяснить их все. В этом случае вместо того, чтобы вычислять просто сумму y i , вычислите сумму j-й степени x i для всех 1 ≤ j ≤ k (я предположил, что x i - это пропущенные числа, а y i - входные числа):
Помните , что вы можете вычислить просто, потому что S 1 = S - Е у я , S 2 = Σ я 2 - Σ у 2 я , ...
Теперь, чтобы найти пропущенные числа, вы должны решить чтобы найти все x i .
Вы можете вычислить:
, P 2 = ∑ x i ⋅ x j , ..., P k = ∏ x i ( 2 ) .
Для этого помните, что , P 2 = S 2 1 - S 2 , ...
Но - это коэффициенты P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ), но P можно учесть однозначно, поэтому вы можете найти пропущенные числа.
Это не мои мысли; прочитайте это .
Из комментария выше:
Перед обработкой потока, выделение бит, в котором вы пишете х : = ⨁ п я = 1 б я п ( я ) ( б я п ( я ) является двоичным представлением I и ⊕ точечен исключающим или). Наивно, это занимает O ( N ) время.
После обработки потока, всякий раз , когда один считывает число , вычислить х : = х ⊕ б я п ( J ) . Пусть к будет одно число из { 1 , . , , n } это не входит в поток. Прочитав весь поток, мы имеем x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b получением желаемого результата.
Следовательно, мы использовали пространство и имели общее время выполнения O ( n ) .
value
биты, но я уверен, что вы можете легко показать, как на самом деле устанавливается только это количество бит.
Для тех, кто хочет псевдокод, используя простой операция с эксклюзивом или ():
Волнообразное доказательство: A никогда не требует большего количества бит, чем его вход, поэтому из вышесказанного не требуется, чтобы промежуточный результат, описанный выше, требовал больше, чем максимальные биты ввода (поэтому биты). коммутативен, и таким образом, если вы расширите вышеприведенное и объедините все данные, присутствующие в потоке, у вас останется только одно несоответствующее значение, отсутствующее число.
#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;
}