Bạn có thể thực hiện tất cả những điều này trong thời gian khấu hao dự kiến . Thủ thuật cơ bản là chúng ta không cần toàn bộ sức mạnh của hàng đợi ưu tiên, vì tần số khóa chỉ thay đổi 1 trong mỗi lần chèn hoặc xóa.O(1)
Giải pháp của tôi dưới đây thực sự chỉ là giải pháp của bạn với hàng đợi ưu tiên "không hiệu quả" sẽ hoạt động tốt trong trường hợp này: hàng đợi ưu tiên tối đa được triển khai dưới dạng danh sách các khóa của các khóa có O (1) insertMin, xóaMax, removeFromBucket và tăng phím.
Duy trì một danh sách các nhóm được liên kết đôi, trong đó mỗi Nhóm có một bộ khóa băm không trống (mà tôi sẽ gọi là một nhóm) và một số nguyên dương (mà tôi sẽ gọi là ValCount). Trong Nhóm b, mỗi khóa k trong Nhóm của b có cùng số lượng giá trị duy nhất được liên kết với nó trong tập hợp bạn đang duy trì. Ví dụ: nếu bộ của bạn có các cặp (a, táo), (a, bơ), (b, chuối), (c, dưa chuột), (d, thanh long) trong đó các chữ cái duy nhất là chìa khóa và các loại trái cây các giá trị, sau đó bạn sẽ có hai Nhóm: Một nhóm sẽ có ValCount là 2 và Nhóm chỉ bao gồm một khóa: a. Nhóm khác sẽ có ValCount là 1 và Cohort bao gồm ba khóa b, c và d.
Danh sách liên kết đôi của Buck phải được ValCount giữ theo thứ tự. Điều quan trọng là chúng ta có thể tìm thấy phần đầu và phần đuôi của danh sách trong thời gian và chúng ta có thể ghép trong một Nhóm mới trong thời gian O ( 1 ) nếu chúng ta biết hàng xóm của mình. Không thể tưởng tượng được, tôi sẽ gọi danh sách Buckets là Nhóm danh sách.O(1)O(1)
Ngoài Nhóm danh sách, chúng tôi sẽ cần SetMap, đây là khóa ánh xạ băm cho ValueBuckets. ValueBucket là một cặp bao gồm Value set (một bộ giá trị băm không trống) và một con trỏ không null cho một nhóm. Giá trị được liên kết với khóa k chứa tất cả các giá trị duy nhất được liên kết với k. Con trỏ nhóm được liên kết với Value set có Cohort bằng với kích thước của Value set. Nhóm được liên kết với khóa k trong SetMap cũng được liên kết với khóa k trong Nhóm liệt kê.
Trong 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;
Để tìm cặp giá trị khóa tần số tối đa, chúng ta chỉ cần nhìn vào phần đầu của Nhóm liệt kê, tìm một khóa trong Cohort, tìm khóa đó trong SetMap và tìm giá trị trong Value set của ValueBucket. (phew!)
Chèn và xóa các cặp khóa-giá trị là khó khăn hơn.
Để chèn hoặc xóa cặp khóa-giá trị, trước tiên chúng tôi chèn hoặc xóa nó trong SetMap Điều này sẽ thay đổi kích thước của Value set, vì vậy chúng tôi cần sửa đổi Nhóm liên kết với khóa. Các thùng duy nhất chúng ta sẽ cần xem xét để thực hiện thay đổi này sẽ là hàng xóm trực tiếp của Xô mà chìa khóa đã từng sử dụng. Có một số trường hợp ở đây và có lẽ chúng không đáng để đánh vần đầy đủ, mặc dù tôi rất vui để giải thích nếu bạn vẫn gặp khó khăn.