Misalkan kita membaca urutan angka, satu per satu. Cara menemukan elemen terkecil hanya dengan menggunakan memori sel dan dalam waktu linier ( ). Saya pikir kita harus menabung dulu hal urutan dan ketika mendapatkan 'jangka th, menghapus istilah yang kita yakin bahwa itu tidak bisa menjadi ' th elemen terkecil dan kemudian save 'jangka th. Jadi kita harus memiliki indikator yang menunjukkan istilah tidak dapat digunakan ini di setiap langkah dan indikator ini harus diperbarui di setiap langkah dengan cepat. Saya mulai dengan "maks"; tetapi tidak dapat memperbarui dengan cepat; Berarti jika kita mempertimbangkan maks maka dalam penghapusan pertama kita kehilangan maks dan kita harus mencari maks dalam dan penyebabnya waktu itu tidak linier. Mungkin kita harus menyimpan terlebih dahulu syarat urutan lebih cerdas.
Bagaimana saya mengatasi masalah ini?
sumber
Jawaban:
Buat buffer ukuran . Baca dalam elemen 2 k dari array. Gunakan algoritma pemilihan waktu linier untuk mempartisi buffer sehingga elemen terkecil k adalah yang pertama; ini membutuhkan waktu O ( k ) . Sekarang baca item k lain dari array Anda ke buffer, ganti item k terbesar di buffer, partisi buffer seperti sebelumnya, dan ulangi.2k 2k k O(k) k k
Ini membutuhkan waktu dan O ( k ) ruang.O(k∗n/k)=O(n) O(k)
sumber
min
Anda dapat melakukannya dalam memori dan waktu O ( n log k ) dengan membentuk he-max max heap dari elemen k pertama dalam waktu O ( k ) , kemudian mengulangi sisa array dan mendorong yang baru elemen dan kemudian muncul untuk O ( log k ) untuk setiap elemen yang memberikan total waktu O ( k + n log k ) = O ( n log k ) .O(k) O(nlogk) k O(k) O(logk) O(k+nlogk) O(nlogk)
Anda dapat melakukannya dalam memori tambahan dan waktu O ( n ) dengan menggunakan algoritma pemilihan median-of-median, memilih pada k , dan mengembalikan elemen k pertama . Tanpa perubahan asimtotik, Anda dapat menggunakan introselect untuk mempercepat kasing rata-rata. Ini adalah cara kanonik untuk menyelesaikan masalah Anda.O(logn) O(n) k k
Sekarang secara teknis dan O ( k ) tidak ada bandingannya. Namun saya berpendapat bahwa O ( log n ) lebih baik dalam praktiknya, karena secara efektif konstan mengingat tidak ada sistem komputer yang memiliki lebih dari 2 64 byte memori, log 2 64 = 64 . Sementara itu k dapat tumbuh hingga sebesar n .O(logn) O(k) O(logn) 264 log264=64 k n
sumber