Кэш LFU, как получить и установить в O(1)?

Готовясь к интервью, я столкнулся с чем-то, что заставляет меня усомниться в моем понимании больших алгоритмов с постоянным временем.

Вопрос о LeetCode просит создать решение проблемы кэширования LFU.

Есть 3 способа реализации:

Конструктор - Ввод: int Capacity

get - ввод: int key - вывод: int

set - ввод: ключ int, значение int

Емкость представляет собой максимальное количество кэшированных пар ключ / значение, которое вы можете хранить одновременно. Когда емкость нарушена, вы должны извлечь наименее часто используемую пару.

Очевидно, что вы должны следить за количеством обращений к каждому элементу.

В нижней части вопроса спрашивается, можете ли вы одновременно получить и установить время O(1).

Я смотрю на несколько предложенных реализаций этого, с длинными списками людей, согласных, что они являются примерами реализаций с постоянным временем, но для меня они выглядят как O(N).

Полный пример см. Здесь: https://leetcode.com/problems/lfu-cache/discuss/94515/Java-O(1)-Accept-Solution-Using-HashMap-DoubleLinkedList-and-LinkedHashSet?page=1

Но соответствующие методы из этого примера находятся в следующем блоке кода. Обратите внимание, что valueHash и nodeHash - это хеш-таблицы java.

public int get(int key) {
    if (valueHash.containsKey(key)) {
        increaseCount(key);
        return valueHash.get(key);
    }
    return -1;
}

    public void set(int key, int value) {
    if ( cap == 0 ) return;
    if (valueHash.containsKey(key)) {
        valueHash.put(key, value);
    } else {
        if (valueHash.size() < cap) {
            valueHash.put(key, value);
        } else {
            removeOld();
            valueHash.put(key, value);
        }
        addToHead(key);
    }
    increaseCount(key);
}

Методы вызывают Hashtable.containsKey и Hashtable.get, которые реализуют линейный поиск. Так что сложность времени в худшем случае - это O (N), верно? Что мне не хватает?

1 ответ

Какую бы структуру данных вы не использовали, она имеет некоторое пессимистическое время поиска T(n), зависящее от количества хранимых элементов, n. Если вы устанавливаете максимальную пропускную способность Nmax и сохраняете ее постоянной в течение времени выполнения вашей программы, как это конкретно требуется в формулировке задачи, тогда максимальное время для обработки любого запроса равно T(Nmax), которое является постоянным.

Благодарим @Zabuza за то, что он подчеркивает постоянный характер Nmax.

Другие вопросы по тегам