← Назад

706.Design HashMap

Ссылка на задачу: https://leetcode.com/problems/design-hashmap/description/


массивы

easy

хеш-таблицы


Описание

Спроектируйте хеш-таблицу без использования каки-либо встроенных библиотек, в которых уже есть реализация хеш-таблиц и прочего.

Имплементация класса MyHashMap:


Примеры

Пример 1

Input:

“MyHashMap""put""put""get""get""put""get""remove""get”
[][1, 1][2, 2][1][3][2, 1][2][2][2]

Output:

nullnullnull1-1null1null-1

Объяснение:


Ограничения


Решение

Вспомним определение структуры данных хеш-таблица. Данная структура данных хранит только уникальные ключи, причем доступ до ключа, добавление соответствующего ему значения и удаление - операции, сложность которых О(1), то есть не зависимая от размера структуры. Строгость порядка элементов отсутствует, он не гарантирован.

Задача сводится к тому, чтобы придумать, как спроектировать класс MyHashMap, удовлетворяющий всем этим условиям. Интуитивно понятно, что нужно использовать какой-то фундаментальный контейнер “под капотом”. Но какой?

Будем идти по порядку условий:

Как будто бы массив почти подходит. Два фактора мешают его использовать: необходимость иметь достаточную емкость для добавления элемента за О(1) и сдвиг элементов при удалении. Нужно как-то нивелировать эти недостатки.

Первую проблему можно решить, обратившись к ограничениям задачи. Сказано, что key лежит в диапазоне от 0 до 10^6 включительно. Так, если мы заранее выделим память под 1000001 целочисленных элементов, то нам всегда хватит емкости с 100%-ной гарантией. Действительно, если key принять за индекс массва, то максимальный индекс - это 10^6, значит размер массива должен быть 1000001, чтобы никогда не выйти за его границы.

В таком подходе вторая проблема тоже решается. Выделив память заранее под самый максимально длинный массив, мы откинули в строноу проблему сдвига элементов при удалении. Вместо сдвига элементов при удалении мы будем приравнивать удаляемому элементу с индексом key некоторое специальное значение. В качестве такого значения отлично подойдет -1, так как именно -1 от нас требуют возвращать в реализации метода get, если key отсутствует в хеш-таблице.

Алгоритм:

  1. Инициализировать массив размером 1000001 значениями -1

  2. В случае попытки взять значение ключа key нужно вернуть значение массива с индексом key

  3. При добавлении по ключу key значения необходимо переписать значение массива с индексом key

  4. При удалении по ключу key достаточно присвоить -1 элементу массива с индексом key

Код:

python

class MyHashMap:
    def __init__(self):
        self.key_to_value = [-1] * (10**6 + 1)

    def put(self, key: int, value: int) -> None:
        self.key_to_value[key] = value

    def get(self, key: int) -> int:
        return self.key_to_value[key]

    def remove(self, key: int) -> None:
        self.key_to_value[key] = -1

C++

class MyHashMap {
public:
    MyHashMap() {
        key_to_value_ = vector<int>(1000001, -1);
    }
    
    void put(int key, int value) {
        key_to_value_[key] = value;
    }
    
    int get(int key) {
        return key_to_value_[key];
    }
    
    void remove(int key) {
        key_to_value_[key] = -1;
    }
private:
    vector<int> key_to_value_;
};

Сложность

Наша хеш-таблица удовлетворяет всем требованиям: