Pertanyaan ini dan pertanyaan ini membuat saya berpikir sedikit. Untuk menyortir array panjangdengan elemen unik di , kita harus dapat menyimpan jumlah nilai dalam array. Ada beberapa saran, tapi saya sedang mencari cara untuk melakukan ini dalam kasus linear terburuk. Lebih spesifik:
Mengingat daftar dari unsur dengan unsur yang berbeda, menentukan daftar tupel dari semua elemen yang unik sehingga adalah hitungan elemen di .
Berikut adalah beberapa (gagal) ide yang saya miliki dan telah disarankan:
- Balanced Binary Search Tree - Dengan ini akan membutuhkan untuk memasukkan ke dalam pohon dan meningkatkan nilai. Setelah memasukkan kita bisa melakukan traversal pohon di . Jadi, total waktu keluar ke yang terlalu lambat.
- Hash Map - Dengan ini kita bisa mendapatkan sisipan yang diharapkan dan dengan demikian perkiraan waktu. Namun, ini masih bukan kasus terburuk.
- Mengosongkan ruang Pemetaan - Cari minimum dan elemen maksimum di . Mengalokasikan (tapi jangan tidak menginisialisasi) cukup memori untuk menutupi kisaran ini. Gunakan memori ini pada dasarnya sebagai peta hash dan sertakan hash acak sehingga kami tidak mencoba mengakses memori yang rusak. Strategi ini menghadirkan masalah. (1) Ini probabilistik dengan kemungkinan kegagalan yang sangat sangat sangat rendah, tetapi masih belum dijamin. Menggunakan memori seperti ini membatasi kita pada batasan floating-point atau integer.
- Array Asosiatif - Ada banyak array asosiatif lainnya yang dapat digunakan, mirip dengan peta hash dan BST, tetapi saya tidak menemukan yang cocok dengan batasan ini.
Mungkin ada beberapa metode yang jelas saya lewatkan, tetapi saya juga berpikir itu bisa berpotensi tidak mungkin. Apa yang kamu pikirkan?
Jawaban:
Ini pertanyaan yang bagus.
Dalam model perbandingan atau, yang lebih umum, model pohon keputusan aljabar, masalah perbedaan elemen memiliki batas yang lebih rendah.Θ ( n logn ) kompleksitas waktu dalam kasus terburuk seperti yang dikatakan dalam artikel Wikipedia ini . Jadi tidak ada algoritma untuk menghitung elemen yang berbeda dalam waktu linier dalam kasus terburuk, bahkan tanpa menghitung duplikat.
Namun, tidak jelas apakah itu dapat dilakukan dalam model komputasi lain. Tampaknya tidak mungkin dalam model komputasi deterministik yang masuk akal.
sumber
Ada algoritma acak yang waktu berjalannya diharapkanO ( n ) ; atau di mana probabilitas bahwa waktu berjalan lebih lama daric n secara eksponensial kecil c .
Secara khusus, secara acak memilih fungsi hash 2-universal, kemudian menggunakannya untuk hash semua elemen array. Ini mencapai waktu berjalan yang dinyatakan, jika Anda memilih panjang output hash 2-universal dengan tepat.
Sebagai contoh lain, Anda dapat membangun algoritma acak yang waktu menjalankannya paling burukO ( n ) (Selalu berjalan dalam waktu linier, tidak peduli apa) dan memiliki kemungkinan kesalahan paling banyak 1 /2100 . (Bagaimana? Jalankan algoritma di atas, dan hentikan jika berjalan lebih lama daric n langkah-langkah untuk beberapa dipilih dengan tepat c .) Dalam praktiknya, itu cukup baik, karena kemungkinan komputer Anda mengeluarkan jawaban yang salah karena sinar kosmik sudah jauh lebih tinggi daripada 1 /2100 .
sumber
Pendekatan Anda 3 dapat dibuat aman menggunakan solusi untuk latihan 2.12 dari Aho, Hopcroft, dan Ullman (1974) Desain dan Analisis Algoritma Komputer seperti yang dijelaskan, misalnya, dalam Menggunakan memori yang tidak diinisialisasi untuk kesenangan dan keuntungan .
Pada dasarnya, selain array N elemen Anda dengan jumlah Anda memiliki dua array elemen N dan satu jumlah tambahan untuk membuat set jarang yang menunjukkan jumlah mana yang valid.
Dalam pseudocode mirip-C:
Implementasi praktis dari set jarang dibahas dalam jawaban StackOverflow ini .
sumber
c
dapat diindeks padax
atauidx
, tapi saya menggunakanidx
untuk cache lokalitas yang lebih baik.{a,b,c,len}
struct untukc
bukan array counts. Misalnya, jika Anda menggunakan radix 512 sehingga masing-masing array cocok dalam satu halaman (dengan pointer 8-byte), maka Anda dapat naik ke