Anda dapat melakukan semua ini dalam perkiraan waktu diamortisasi. Trik penting adalah bahwa kita tidak memerlukan kekuatan penuh dari antrian prioritas, karena frekuensi kunci hanya berubah sebesar 1 selama setiap penyisipan atau penghapusan.O ( 1 )
Solusi saya di bawah ini benar-benar hanya solusi Anda dengan antrian prioritas "tidak efisien" yang berfungsi dengan baik untuk kasus ini: antrian prioritas maksimum diimplementasikan sebagai daftar ember kunci yang tertaut ganda memiliki O (1) insertMin, deleteMax, removeFromBucket, dan tingkatkan kunci.
Menyimpan daftar Bucket yang tertaut ganda, di mana setiap Bucket memiliki kumpulan kunci hash yang tidak kosong (yang akan saya sebut Cohort) dan bilangan bulat positif (yang saya sebut ValCount). Dalam Bucket b, setiap kunci k dalam Cohort of b memiliki jumlah nilai unik yang sama dengan yang ada dalam set yang Anda pertahankan. Misalnya, jika set Anda memiliki pasangan (a, apel), (a, alpukat), (b, pisang), (c, mentimun), (d, buah naga) di mana huruf tunggal adalah kunci dan buahnya adalah nilainya, maka Anda akan memiliki dua Bucket: Satu Bucket akan memiliki ValCount 2 dan Cohort yang hanya terdiri dari satu kunci: a. Bucket lainnya akan memiliki ValCount 1 dan Cohort yang terdiri dari tiga kunci b, c, dan d.
Daftar Bucket yang tertaut ganda harus tetap dipesan oleh ValCount. Penting bahwa kita dapat menemukan kepala dan ekor daftar dalam waktu dan bahwa kita dapat menyambungkan dalam Bucket baru dalam waktu O ( 1 ) jika kita tahu tetangganya. Secara tidak imajinatif, saya akan menyebut daftar Bucket BucketList.O ( 1 )O ( 1 )
Selain BucketList, kita membutuhkan SetMap, yang merupakan kunci pemetaan peta hash untuk ValueBuckets. ValueBucket adalah pasangan yang terdiri dari ValueSet (set nilai hash yang tidak kosong) dan pointer non-null ke Bucket. ValueSet yang terkait dengan kunci k berisi semua nilai unik yang terkait dengan k. Pointer Bucket yang terkait dengan ValueSet memiliki Kohort yang sama dengan ukuran ValueSet. Bucket yang terkait dengan kunci k di SetMap juga dikaitkan dengan kunci k di BucketList.
Dalam C ++:
struct Bucket {
unsigned ValCount;
unordered_set<Key> Cohort;
Bucket * heavier;
Bucket * lighter;
};
Bucket * BucketListHead;
Bucket * BucketListTail;
struct ValueBucket {
unordered_set<Value> ValueSet;
Bucket * bucket;
};
unordered_map<Key, ValueBucket> SetMap;
Untuk menemukan pasangan nilai kunci frekuensi maksimum, kita hanya perlu melihat kepala BucketList, menemukan kunci dalam Cohort, mencari kunci itu di SetMap, dan menemukan nilai dalam ValueSet dari ValueBucket-nya. (Fiuh!)
Memasukkan dan menghapus pasangan nilai kunci lebih sulit.
Untuk menyisipkan atau menghapus pasangan nilai kunci, pertama-tama kita menyisipkan atau menghapusnya di SetMap. Ini akan mengubah ukuran ValueSet, jadi kita perlu memodifikasi Bucket yang terkait dengan kunci tersebut. Satu-satunya Bucket yang perlu kita perhatikan untuk melakukan perubahan ini adalah tetangga terdekat Bucket yang menjadi kuncinya. Ada beberapa kasus di sini, dan mereka mungkin tidak layak dieja sepenuhnya, meskipun saya akan senang untuk menguraikan jika Anda masih mengalami masalah.