답변:
알다시피 , 때문에 부호화 될 수있다 비트 이것은 메모리와 하나의 경로에서 수행 할 수 있습니다 ( 찾으십시오 .이 숫자는 누락되었습니다). S=n(n+1) O(로그(n))O(로그n)S−currentSum
그러나이 문제는 일반적인 경우 (상수 ) 에서 해결할 수 있습니다 . 우리는 누락 된 숫자 가 있으며 모두 알아냅니다. 이 경우 합을 계산하는 대신 모든 대해 의 j'st 거듭 제곱의 합을 계산하십시오 ( 는 누락 된 숫자이고 는 입력 숫자 라고 가정 합니다).k y i x i 1 ≤ j ≤ k x i y i
, , ... 이므로 간단히 계산할 수 있습니다 .S 1 = S − ∑ y i S 2 = ∑ i 2 − ∑ y 2 i
이제 누락 된 숫자 를 찾으려면 을 풀고 모든 를 찾으십시오 .x 나는
다음을 계산할 수 있습니다.
P 2 = ∑ x i ⋅ x j P k = ∏ x i ( 2 ) , , ..., .
이를 위해 기억이 , , ...
그러나 는 계수 이지만 는 고유하게 인수 분해 되므로 누락 된 숫자를 찾을 수 있습니다.
이것들은 내 생각이 아니다. 이것을 읽으십시오 .
위의 의견에서 :
스트림을 처리하기 전에, 할당 가 연락하는 비트, X : = ⨁ N I = 1 B 나 N ( I ) ( b를 i가 N ( 나 ) 의 이진 표현 난 과 ⊕ 이다 점별 배타적을 또는). 순진하게, 이것은 O ( n ) 시간 이 걸린다 .
하나는 다수의 스트림마다 판독 처리시 , 컴퓨팅 X : = X ⊕ B 나 N ( J ) . k 는 { 1 , 의 단일 숫자라고 하자 . . . n } 스트림에 포함되지 않습니다. 전체 스트림을 읽은 후 x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b 원하는 결과를 얻었다.
따라서, 우리가 사용 공간 및 전반적인 실행이 O ( N을 ) .
HdM의 솔루션이 작동합니다. 테스트하기 위해 C ++로 코딩했습니다. 나는를 제한 할 수 없습니다 value
에 비트,하지만 난 당신이 쉽게 비트의 수는 실제로 설정되어 있는지 방법만을 보여줄 수 있어요.
의사 코드를 원하는 경우 독점 또는 ( ⊕ ) 로 간단한 작업을 사용하십시오 .
손파 방지 : A 는 입력보다 더 많은 비트를 필요로하지 않으므로, 위의 중간 결과가 입력의 최대 비트 ( 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;
}