Görev, istenen sayı listesinin N uzunluğunda O (1) olan bir algoritma bulmaktır. Bu yüzden ilk 100 sayı veya 10000 sayıya ihtiyacınız olursa, ekleme süresi O (1) olmalıdır.
Buradaki hile, listenin eklenmesi için O (1) gereksiniminden söz edilmesine rağmen, sorunun tüm sayı alanındaki arama süresiyle ilgili bir şey söylemediği, ancak bunun O (1) olabileceği ortaya çıktı. yanı sıra. Bu durumda çözüm aşağıdaki gibidir:
Anahtarlar için sayıları olan ve değerler için bağlı liste işaretçilerinin çiftlerini içeren bir karma tablo düzenleyin. Her bir işaretçi çifti, bağlı bir liste dizisinin başlangıcı ve bitişidir. Bu normalde sadece bir eleman, sonra diğeri olacak. Bağlantılı listedeki her öğe, bir sonraki en yüksek sayıya sahip olan öğenin yanına gider. Bağlantılı liste böylece gerekli sayıların sıralanmış sırasını içerir. En düşük sayının kaydını tutun.
Rasgele akıştan yeni bir sayı x alın.
En son kaydedilen en düşük sayıdan daha mı yüksek? Evet => Adım 4, Hayır => Adım 2
Yeni alınan numara ile hash tablosuna basın. Bir giriş var mı? Evet => Adım 5. Hayır => Yeni bir x-1 numarası alın ve bu adımı tekrarlayın (bu basit bir aşağı doğru doğrusal arama, sadece burada yanımda kalın, bu geliştirilebilir ve nasıl açıklayacağım)
Karma öğesinden yeni elde edilen liste öğesiyle, yeni sayıyı, bağlantılı listedeki öğenin hemen arkasına yazın (ve karma değerini güncelleyin).
Kaydedilen en düşük l sayısını alın (ve karma / listeden çıkarın).
Yeni alınan numara ile hash tablosuna basın. Bir giriş var mı? Evet => Adım 8. Hayır => Yeni bir l + 1 numarası alın ve bu adımı tekrarlayın (bu basit bir yukarı doğru doğrusal aramadır)
Olumlu bir vuruşla sayı yeni en düşük sayı olur. 2. adıma gidin
Yinelenen değerlere izin vermek için karma gerçekte yinelenen öğelerin bağlantılı liste dizisinin başlangıcını ve sonunu koruması gerekir. Belirli bir tuşa eleman eklenmesi veya çıkarılması, böylece işaret edilen aralığı arttırır veya azaltır.
Buradaki insert O (1). Bahsedilen aramalar, sanırım, O (sayılar arasındaki ortalama fark) gibi bir şey. Ortalama fark, sayı alanının boyutuyla birlikte artar, ancak sayı listesinin istenen uzunluğu ile azalır.
Bu nedenle, eğer sayı alanı büyükse (ör. 4 baytlık bir int tipi için, 0 ila 2 ^ 32-1) ve N = 100 ise, doğrusal arama stratejisi oldukça zayıftır. Bu performans sorununu çözmek için, uygun anahtarlar yapmak için sayıların daha yüksek büyüklüklere (örneğin 1s, 10s, 100s, 1000s) yuvarlandığı paralel karma setlerini tutabilirsiniz. Bu sayede, gerekli aramaları daha hızlı yapmak için dişlileri yukarı ve aşağı hareket ettirebilirsiniz. Daha sonra performans bir O (log numberrange) olur, bence, yani sabittir, yani O (1).
Bunu daha net hale getirmek için 197 numarasının elinizde olduğunu hayal edin. 10'lu karma masaya çarptın, '190' ile, en yakın 10'a yuvarlandı. Herhangi bir şey? Hayır. Diyelim ki 120'ye kadar isabet edene kadar 10'larda iniyorsunuz. Sonra 1s hashtable'da 129'dan başlayabilir, daha sonra bir şeye çarpıncaya kadar 128, 127 deneyebilirsiniz. Bağlantılı listede 197 sayısını nereye koyacağınızı buldunuz. Bunu koyarken, 1s kodunu 197 girişiyle, 10'larının 190, 100'lerin 100'lü sayısıyla vb. Burada yapmanız gerekenler, sayı aralığının günlüğünün 10 katıdır.
Bazı ayrıntıları yanlış anlamış olabilirim, ancak bu programcıların değişimi olduğu ve bağlamın röportajları olduğu için yukarıdakilerin bu durum için yeterince ikna edici bir cevap olduğunu umuyorum.
EDIT Paralel karma çizelge şemasını açıklamak için buraya bazı ekstra detaylar ekledim ve bahsettiğim zayıf doğrusal aramaların nasıl bir O (1) araması ile değiştirilebileceği anlamına geliyor. Tabii ki bir sonraki en düşük sayıyı aramaya gerek olmadığını da gördüm, çünkü doğrudan en düşük sayıya sahip olan karışıma bakarak ve bir sonraki elemana ilerleyerek doğrudan adım atabilirsiniz.