Możesz to zrobić w oczekiwanym zamortyzowanym czasie. Podstawową sztuczką jest to, że nie potrzebujemy pełnej mocy kolejki priorytetowej, ponieważ częstotliwość klawiszy zmienia się tylko o 1 podczas każdego wstawiania lub usuwania.O(1)
Moje rozwiązanie poniżej to tak naprawdę twoje rozwiązanie z „nieefektywną” kolejką priorytetową, która akurat działa dobrze w tym przypadku: kolejka maksimum priorytetu zaimplementowana jako podwójnie połączone listy segmentów kluczy ma O (1) insertMin, deleteMax, removeFromBucket i wzrostKlucz.
Zachowaj podwójnie połączoną listę segmentów, gdzie każdy segment ma niepusty zestaw kluczy mieszających (które nazywam kohortą) i dodatnią liczbę całkowitą (które nazywam ValCount). W segmencie b każdy klucz k w kohorcie b ma taką samą liczbę unikalnych wartości związanych z nim w zestawie, który utrzymujesz. Na przykład, jeśli twój zestaw zawiera pary (a, jabłko), (a, awokado), (b, banan), (c, ogórek), (d, owoc smoka), gdzie pojedyncze litery to klucze, a owoce to wartości, wtedy miałbyś dwa Wiadra: Jeden Wiadro miałby ValCount 2 i Kohortę składającą się tylko z jednego klucza: a. Drugi segment miałby wartość ValCount równą 1 i kohortę złożoną z trzech kluczy b, c i d.
ValCount powinna przechowywać uporządkowaną podwójnie listę Bucket. Ważne będzie, abyśmy mogli znaleźć głowę i ogon listy w czasie i abyśmy mogli podzielić na nowy segment Wiadra w czasie jeśli znamy jego sąsiadów. Niewyobrażalnie nazywam listę Buckets listą BucketList.O(1)O(1)
Oprócz BucketList potrzebujemy SetMap, który jest kluczem mapującym mapę skrótów do ValueBuckets. ValueBucket to para składająca się z ValueSet (niepustego zestawu wartości skrótu) i niepustego wskaźnika do segmentu. ValueSet powiązany z kluczem k zawiera wszystkie unikalne wartości związane z k. Wskaźnik segmentu skojarzony z ValueSet ma kohortę równą wielkości ValueSet. Wiadro powiązane z kluczem k w SetMap jest również powiązane z kluczem k w BucketList.
W 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;
Aby znaleźć parę klucz-wartość o maksymalnej częstotliwości, wystarczy spojrzeć na nagłówek BucketList, znaleźć klucz w kohorcie, wyszukać ten klucz w SetMap i znaleźć wartość w ValueSet jego ValueBucket. (uff!)
Wstawianie i usuwanie par klucz-wartość jest trudniejsze.
Aby wstawić lub usunąć parę klucz-wartość, najpierw wstawiamy lub usuwamy ją w SetMap. Spowoduje to zmianę rozmiaru ValueSet, dlatego musimy zmodyfikować segment powiązany z kluczem. Jedynymi wiadrami, na które musimy spojrzeć, aby dokonać tej zmiany, będą najbliżsi sąsiedzi wiadra, w którym kiedyś był klucz. Jest tu kilka przypadków i prawdopodobnie nie warto ich w pełni opisywać, chociaż byłbym szczęśliwy rozwinąć, jeśli nadal masz problemy.