Хеш-таблицы

Базовый Algorithms
≈ 2 мин чтения

Зачем нужны хеш-таблицы

Во многих алгоритмических задачах постоянно повторяется один и тот же вопрос: «мы уже встречали это значение?» или «какие данные связаны с этим ключом?». Если каждый раз просматривать массив с начала, один поиск может занимать O(n). Хеш-таблица позволяет организовать данные так, чтобы поиск, добавление и удаление в среднем выполнялись за O(1).

За этой скоростью стоит простая идея: ключ преобразуется в хеш, а хеш помогает быстро выбрать место, где нужно искать запись. Но между этой идеей и надёжной структурой данных есть несколько важных шагов — хорошая хеш-функция, обработка коллизий и правильный выбор между хранением пар «ключ — значение» и простым множеством значений.

Что входит в раздел

  • Основы хеш-таблиц. Разберём общую схему «ключ → хеш → корзина» и поймём, откуда берётся быстрый доступ к данным.
  • Хеш-функции. Поговорим о свойствах хеша и о том, почему одинаковые ключи должны обрабатываться согласованно.
  • Коллизии. Увидим, почему разные ключи иногда попадают в одно место и как хеш-таблица сохраняет корректность в такой ситуации.
  • Hash Map. Научимся быстро находить значение по ключу и выбирать такую структуру для алгоритмических задач.
  • Hash Set. Разберём хранение уникальных значений и быстрые проверки принадлежности множеству.
  • Частотная карта. Освоим один из самых частых приёмов: подсчёт количества появлений каждого значения.
  • Паттерны быстрого поиска. Соединим знания раздела и увидим, как дополнительная память помогает заменять повторные линейные поиски быстрыми проверками.

Одна структура — много алгоритмических приёмов

Set<Integer> seen = new HashSet<>();
seen.add(42);

boolean exists = seen.contains(42);

Здесь проверка наличия значения выглядит почти как обычный вопрос к структуре данных. В следующих темах разберём, почему такая проверка может быть быстрой и как на той же идее строятся карты, множества, подсчёты частот и многие задачи на поиск.