Подготовка к собеседованию часто сводится к пугающей цифре: «Нужно решить 500 задач на LeetCode». Но зубрить сотни решений неэффективно. Большинство задач на алгоритмических секциях решаются с помощью нескольких базовых паттернов.
Если вы поймёте суть паттерна — не код, а ход мыслей — вы сможете решить задачу, которую видите впервые. Ниже — 6 фундаментальных шаблонов с «алгоритмом мыслей», маркерами (по каким признакам понять, что нужен именно этот паттерн) и примерами классических задач.
1. Arrays + HashMap
Этот паттерн используется, когда нужно избежать вложенных циклов O(n²) и ускорить поиск за счёт дополнительной памяти. Мы жертвуем памятью O(n) ради скорости O(n).
- 1 Создаю память:
Set(для уникальности) илиMap(для частот / пар). - 2 Иду по массиву в цикле.
- 3 Для текущего элемента задаю вопрос: «Что мне нужно узнать из уже обработанного прошлого?»
- 4 Если ответ уже есть в памяти → делаю действие:
return/count++/add result. - 5 Если нет (или после обработки) → записываю текущий элемент в память.
2. Two Pointers
Идеальный способ оптимизировать вложенный цикл при работе с линейными структурами данных. Вместо перебора всех пар используем два индекса, которые двигаются по массиву.
- 1 Ставлю два указателя:
leftиright. - 2 Обычно
leftв начале,rightв конце (или оба в начале с разной скоростью). - 3 Смотрю на пару элементов под указателями.
- 4 Задаю вопрос: «Какой указатель нужно сдвинуть, чтобы приблизиться к ответу?»
- 5 Двигаю нужный указатель.
- 6 Повторяю, пока
left < right.
3. Sliding Window
Развитие идеи двух указателей. Окно — это подмассив или подстрока, которая «скользит» по данным. Используется для поиска оптимального непрерывного участка.
- 1 Создаю окно: два указателя
leftиright. - 2 Двигаю
rightи расширяю окно. - 3 Добавляю текущий элемент в состояние окна:
sum/count/map/set. - 4 Проверяю: «Окно всё ещё валидно?»
- 5 Если невалидно → двигаю
left, удаляю элементы из состояния, пока окно снова не станет валидным. - 6 После каждого валидного окна обновляю ответ:
max/min/count.
Паттерны — это база. Но на собесе нужна система.
На менторских сессиях мы разбираем эти паттерны на реальных задачах с собеседований в Яндекс, Авито и Тинькофф — с живым code review и честной обратной связью.
4. Binary Search
Магия O(log n). Если вы можете отбросить половину вариантов за один шаг — используйте бинарный поиск. Работает не только с отсортированными массивами, но и с любым пространством ответов, где можно проверить true/false.
- 1 Данные отсортированы или ответ можно проверять через
true/false(бинарный поиск по ответу). - 2 Ставлю границы:
leftиright. - 3 Беру середину:
mid = left + (right - left) / 2. - 4 Задаю вопрос: «Ответ левее, правее или это он?»
- 5 Если ответ меньше →
right = mid - 1. Если больше →left = mid + 1. - 6 Повторяю, пока
left <= right.
5. DFS / BFS
Необходимы, когда данные не линейны, а имеют связи: деревья, графы, матрицы, сетки. Это фундамент для задач, где нужно что-то найти, обойти или проверить связность.
- 1 Понимаю структуру: граф / дерево / сетка (матрица).
- 2 Создаю
visited, чтобы не ходить по кругу. - 3 Выбираю обход: DFS — вглубь (рекурсия / Stack), BFS — слоями (Queue).
- 4 Беру текущую вершину / клетку.
- 5 Проверяю: «Это ответ или надо идти к соседям?»
- 6 Добавляю соседей, если валидные и не посещены.
- 7 Повторяю, пока есть куда идти.
6. Stack
Стек (LIFO — Last In, First Out) идеален для задач, где нужно отслеживать парность, вложенность, отмену действий или сравнивать текущий элемент с предыдущими.
- 1 Создаю стек (в Kotlin это
ArrayDeque). - 2 Иду по элементам входных данных.
- 3 Для текущего элемента задаю вопрос: «Он закрывает / отменяет / сравнивается с верхушкой стека?»
- 4 Если да → делаю
pop(или серию pop). - 5 Если нет → делаю
push. - 6 В конце проверяю пустоту стека или собираю результат.
Как с этим работать на собеседовании
Не пытайтесь сразу написать идеальный код. На собеседовании сначала вслух проговорите алгоритм мыслей из этой шпаргалки:
Прочитайте условие и найдите маркер: «подстрока» → Sliding Window, «отсортирован» → Binary Search
Назовите паттерн вслух интервьюеру: «Я вижу здесь задачу на два указателя, потому что…»
Пройдите по шагам алгоритма мыслей на примере из условия, прежде чем писать код
Напишите код, комментируя каждую часть: «тут я расширяю окно, тут сжимаю…»
Алгоритмические паттерны — это мышечная память. Чем чаще вы применяете эти 6 подходов на практике, тем быстрее будете «щелкать» задачи на лайв-кодинге. Но если вы чувствуете, что паттерны знаете, а на собеседовании всё равно теряетесь — скорее всего, проблема не в знаниях, а в отсутствии системы и тренировки подачи.