İşte alanı O(N)kullanan basit bir çözüm O(N). Giriş listesini negatif olmayan sayılarla sınırladığımızı ve listede olmayan ilk negatif olmayan sayıyı bulmak istediğimizi varsayıyorum.
- Listenin uzunluğunu bulun; diyelim öyle
N.
NHepsi için başlatılan bir boole dizisi ayırın false.
XListedeki her sayı için, eğer Xküçükse N, X'thdizinin öğesini olarak ayarlayın true.
- Diziyi dizinden başlayarak
0ilk öğeyi arayarak tarayın false. İlkini falsedizinde bulursanız I, o zaman Icevaptır. Aksi takdirde (yani tüm unsurlar olduğu zaman true) cevaptır N.
Pratikte, " Nmantıksal değer dizisi " muhtemelen bir byteveya intdizi olarak temsil edilen "bit eşlem" veya "bit kümesi" olarak kodlanacaktır . Bu genellikle daha az alan kullanır (programlama diline bağlı olarak) ve ilk taramanın falsedaha hızlı yapılmasını sağlar.
Algoritmanın nasıl / neden çalıştığı budur.
NListedeki sayıların farklı olmadığını veya bir veya daha fazlasının değerinden büyük olduğunu varsayalım N. Bu , listede olmayan aralıkta en az bir sayı olması gerektiği anlamına gelir 0 .. N - 1. Bu nedenle, en küçük eksik sayıyı bulma sorunu, bu nedenle, en küçük eksik sayıyı daha azN bulma sorununa indirgemelidir . Bu, büyük veya eşit sayıları takip etmemize gerek olmadığı anlamına gelir N... çünkü cevap onlar olmayacaktır.
Önceki paragrafın alternatifi, listenin, gelen sayıların bir permütasyonu olmasıdır 0 .. N - 1. Bu durumda, 3. adım dizinin tüm öğelerini olarak ayarlar trueve 4. adım bize ilk "eksik" sayının olduğunu söyler N.
Algoritmanın hesaplama karmaşıklığı, O(N)nispeten küçük bir orantılılık sabiti ile. Listede iki doğrusal geçiş yapar veya liste uzunluğunun başladığı biliniyorsa yalnızca bir geçiş yapar. Listenin tamamını bellekte tutmaya gerek yoktur, bu nedenle algoritmanın asimtotik bellek kullanımı boole dizisini temsil etmek için gereken şeydir; yani O(N)bitler.
(Aksine, bellek içi sıralama veya bölümlemeye dayanan algoritmalar, tüm listeyi bellekte temsil edebileceğinizi varsayar. Sorunun sorulduğu biçimde, bu O(N)64 bit sözcükler gerektirir .)
@Jorn, 1'den 3'e kadar olan adımların sıralamayı saymanın bir varyasyonu olduğunu söylüyor. Bir bakıma haklı ama farklar önemli:
- Sayma sıralaması , listedeki en büyük sayı ve listedeki en küçük sayı olan (en azından) bir
Xmax - Xminsayaç dizisi gerektirir . Her sayaç N durumu temsil edebilmelidir; yani bir ikili gösterimi varsayarsak, tam sayı tipinde (en azından) bitlere sahip olmak zorundadır .XmaxXminceiling(log2(N))
- Dizi boyutunu belirlemek için, bir sayma sıralaması
Xmaxve belirlemek için listeden bir ilk geçiş yapması gerekir Xmin.
- Bu nedenle minimum en kötü durum alanı gereksinimi
ceiling(log2(N)) * (Xmax - Xmin)bittir.
Aksine, yukarıda sunulan algoritma basitçe Nen kötü ve en iyi durumlarda bit gerektirir .
Bununla birlikte, bu analiz, eğer algoritma bir sıfırı bulmak için listeden bir ilk geçiş yaparsa (ve gerekirse liste öğelerini sayarsa), sıfırı bulursa hiç boşluk kullanmadan daha hızlı bir cevap vereceği sezgisine yol açar. Listede en az bir sıfır bulma olasılığı yüksekse kesinlikle bunu yapmaya değer. Ve bu ekstra geçiş genel karmaşıklığı değiştirmez.
DÜZENLEME: Algoritmanın açıklamasını "boole dizisi" kullanacak şekilde değiştirdim çünkü insanlar görünüşe göre orijinal açıklamamı bitler ve bit eşlemler kullanarak kafa karıştırıcı buldular.