Kami menerima aliran angka yang berbeda secara berpasangan dari set .
Bagaimana saya bisa menentukan angka yang hilang dengan algoritma yang membaca aliran sekali dan menggunakan memori hanya bit?
Kami menerima aliran angka yang berbeda secara berpasangan dari set .
Bagaimana saya bisa menentukan angka yang hilang dengan algoritma yang membaca aliran sekali dan menggunakan memori hanya bit?
Anda tahu , dan karenaS=n(n+1) dapat dikodekan dalambitO(log(n))ini dapat dilakukan dalammemoriO(logn)dan dalam satu jalur (cukup cariS-currentSum, ini adalah nomor yang hilang).
Tetapi masalah ini dapat diselesaikan dalam kasus umum (untuk konstan ): kami memiliki nomor k yang hilang, cari tahu semuanya. Dalam hal ini, alih-alih menghitung hanya jumlah y i , hitung jumlah kekuatan pertama x i untuk semua 1 ≤ j ≤ k (saya berasumsi x i adalah angka yang hilang dan y i adalah angka input):
Ingat bahwa Anda dapat menghitung sederhana, karena S 1 = S - Σ y i , S 2 = Σ i 2 - Σ y 2 , ...
Sekarang untuk menemukan nomor yang hilang, Anda harus memecahkan untuk menemukan semua .
Anda dapat menghitung:
, P 2 = ∑ x i ⋅ x j , ..., P k = ∏ x i ( 2 ) .
Untuk ini ingat bahwa , P 2 = S 2 1 - S 2 , ...
Tetapi adalah koefisien dari P tetapi dapat diperhitungkan secara unik, sehingga Anda dapat menemukan angka yang hilang.
Ini bukan pikiran saya; Baca ini .
Dari komentar di atas:
Sebelum memproses aliran, alokasikan bit, di mana Anda menulis x : = ⨁ n i = 1 b i n ( i ) ( b i n ( i⌈ log2n ⌉ x : = ⨁ni = 1b i n (i) adalah representasi biner dari i dan ⊕ adalah pointwise eksklusif- atau). Secara naif, ini membutuhkan waktu O ( n ) .b i n (i) saya ⊕ O (n)
Setelah memproses streaming, setiap kali seseorang membaca angka , hitung x : = x ⊕ b i n ( j ) . Biarkan k menjadi nomor tunggal dari { 1 , . . . n } yang tidak termasuk dalam aliran. Setelah membaca seluruh aliran, kita memiliki x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k bj x : = x ⊕ b i n ( j ) k { 1 , . . . n }
sumber
Solusi HdM bekerja. Saya mengkodekannya dalam C ++ untuk mengujinya. Saya tidak bisa membatasiO ( log2n ) bit, tapi saya yakin Anda dapat dengan mudah menunjukkan bagaimana hanya jumlah bit yang benar-benar ditetapkan.
value
untukBagi yang menginginkan kode pseudo, gunakan yang sederhanamelipat operasi dengan eksklusif atau (⊕ ):
Bukti bergelombang: A⊕ tidak pernah memerlukan lebih banyak bit dari inputnya, jadi itu berarti bahwa tidak ada hasil antara di atas membutuhkan lebih dari bit maksimum input (jadi O ( log2n ) bit). ⊕ bersifat komutatif, dan x ⊕ x = 0 , jadi jika Anda memperluas yang di atas dan memasangkan semua data yang ada dalam aliran Anda akan dibiarkan hanya dengan satu nilai yang tidak cocok, angka yang hilang.
sumber