Практикум: паттерны и план тренировок

Перед началом: весь курс — этот модуль собирает его в систему. Инструменты: Go 1.27, журнал решений (любой). Трудоёмкость: ~4 ч (теория 1.5 ч · практика 2.5 ч) + тренировки дальше.

🔥 Инцидент: «Триста решённых задач — и ступор на собеседовании»

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

📖 Теория

20.1 Каталог паттернов: признак → паттерн → модуль

Паттерн — это не название алгоритма, а связка «признак в условии → структура решения». Учите таблицу слева направо: признак вы увидите раньше, чем вспомните название.

Признак в условииПаттернМодуль
Отсортированный вход, «найти пару/тройку»Два указателя3
«Подотрезок / подстрока / окно» с монотонным условиемСкользящее окно3
«Появлялось ли уже», частоты, группыХеш-таблица4
Суммы на префиксах, «сумма подотрезка = k»Префиксные суммы3
«Следующий больше/меньше», вложенные скобкиМонотонный стек / стек5
«Порядок последних использованных», LRUСписок + map6
«Медиана/середина», цикл в спискеFast/slow указатели6
«Все варианты / комбинации / расстановки»Перебор с возвратом7
«Топ k», «k наименьших», слияние потоковКуча9
Данные отсортированы, поиск границыLower/upper bound10
«Минимальное максимальное / минимальная вместимость»Поиск по ответу10
Обход дерева, «уровни», LCAОбходы дерева / BFS11
Поиск по префиксу, словарьTrie13
Сетка, «достижимость», «острова»BFS/DFS по графу14
«Порядок с зависимостями», цикл в графеТопологическая сортировка14
Группировка/слияние множеств, «лишнее ребро»DSU15
Взвешенный граф, «кратчайший/дешёвый маршрут»Дейкстра15
«Минимальная сеть, соединить всё»MST (Краскал/Прим)15
Интервалы: пересечения, брони, покрытияЖадный по концу18
«Минимум монет/шагов/путей» с выборомDP (1D)16
Рюкзак, «выбрать подмножество с суммой»DP (2D)17
Две строки: расстояние, общая частьDP по двум строкам17
«Самая длинная возрастающая подпоследовательность»LIS: DP или tails+bsearch17
Флаги, чётность, «элемент без пары»Биты и XOR19
Делимость, простые, степени по модулюМатематика19

Полный список — не для заучивания наизусть, а для закрытия пробелов: идите по строкам от модуля 1 к 19 и отмечайте, где «видел, но сам не писал».

20.2 Как узнавать паттерн: сигналы из условия

Три вопроса к условию — до написания кода:

  1. Что дано? Отсортировано → два указателя / бинарный поиск; сетка → граф; два словаря → trie; интервалы → сортировка по концу.
  2. Что просят? «Все варианты» → бэктрекинг; «оптимальное значение» → DP или жадный; «быстро проверить наличие» → хеш; «k из n» → куча.
  3. Что растёт и как? Одна строка → 1D DP; две → таблица; «независимые выборы на каждом шаге» → DP-состояние, а не жадный, если выбор влияет на будущее.

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

20.3 Три задачи end-to-end

Задача 1: LRU-кэш. Признак: «порядок последних использованных» → map (доступ за O(1)) + двусвязный список (порядок за O(1)). Разбор — модуль 6. Схема: get двигает узел в голову; put при переполнении удаляет хвост.

Задача 2: число островов. Признак: «сетка, достижимость» → граф, BFS/DFS. Разбор — модуль 14. Схема: проход по всем клеткам; земля запускает заливку, которая её же и «затапливает» — повторных обходов нет.

Задача 3: edit distance. Признак: «две строки, преобразование» → DP по двум строкам, модуль 17. Схема: таблица (n+1)×(m+1), переход — минимум из трёх; ответ в правом нижнем углу.

Общее у всех трёх: паттерн определил структуру данных, структура — код. Это и есть весь «секрет»: не заучивать решённые задачи, а собирать связки «признак → структура».

20.4 Процесс решения: пять шагов

  1. Уточните вход и крайние случаи. Пустой вход? Отрицательные числа? Дубликаты? Один элемент?
  2. Приведите маленький пример руками. Три-четыре элемента, на бумаге. Именно здесь паттерн проявляется.
  3. Сформулируйте наивное решение и его сложность. Даже O(n²) — это отправная точка и страховка, если не успеете иначе.
  4. Улучшайте или пишите. Если паттерн узнали — сразу целевое решение; если нет — пишите наивное и ищите, что пересчитывается зря.
  5. Проверьте на крайних случаях из шага 1 и проговорите сложность по времени и памяти.

На собеседовании шаги 1–3 важнее кода: интервьюер проверяет мышление, а не скорость набора. Проговаривайте «почему эта структура» — это ровно те доказательства инвариантов, которые вы делали в модулях 3, 10 и 14.

20.5 План тренировок на 8 недель

НеделяТемаЗадач
1Массивы, окно, хеш (модули 2–4)8–10
2Стек, списки, рекурсия (5–7)8–10
3Сортировки, куча, бинарный поиск (8–10)8–10
4Деревья, trie, строки (11–13)8–10
5Графы: обходы, топосорт, DSU (14–15)8–10
6Дейкстра, MST, интервалы (15, 18)6–8
7DP: 1D и 2D (16–17)8–10
8Биты, математика, повторение слабых мест (19)6–8 + повтор

Правила: одна задача — максимум 30 минут самостоятельной работы, потом разбор (не подсматривание кода, а чтение идей). Каждые выходные — 20–30 минут на задачи, где были ошибки: повторение важнее новых задач. Ведите журнал: дата, паттерн, ошибка (узнавание / реализация / крайний случай). Через три недели журнал покажет ваши системные дыры точнее любого списка тем.

20.6 Компромиссы

РешениеЗаПротив
30 мин на задачу, дальше разборНе застреваете, растёт покрытиеПривычка сдаваться быстро
3 часа на задачу, но самГлубина, тренировка упорстваМало паттернов за месяц
Много лёгких задачСкорость, узнаваниеСредних на интервью больше
Мало средних/сложныхРеализм интервьюБольно, если базы нет
Шпаргалка паттерновУскоряет узнаваниеЗаменяет понимание, если раньше времени

Баланс: первые недели — много лёгких (закрепление паттернов), дальше соотношение 1 : 2 лёгких к средним, иначе собеседование на средних застанет врасплох. Шпаргалку пишите сами — по памяти, после недели решений; чужая шпаргалка в голову не переносится.

💻 Практика

  1. Личный каталог паттернов. Заведите таблицу: паттерн, признак, шаблон кода (10–15 строк), 2 задачи-представителя. Заполните по модулям 3–19 из памяти, потом сверьте с §20.1 — расхождения и есть ваши пробелы.
  2. Три шаблона-заготовки. Соберите собственный файл templates.go с готовыми: (а) lower bound бинарного поиска; (б) BFS по сетке с 4 соседями; (в) DP «минимум монет» с 1D-массивом. Требование: каждый шаблон — с тестовым вызовом на фиксированных данных, вывод детерминирован.
  3. Разбор трёх задач end-to-end. Возьмите три задачи из §20.3 и распишите для каждой по шагам §20.4: крайние случаи, пример руками, наивное решение и его сложность, целевое решение. Цель — научиться проговаривать путь, а не только писать код.
  4. Журнал и повтор. Заведите журнал решений по формату из §20.5 и перерешайте три задачи, где вы ошибались, — без подсматривания. Если повторное решение заняло больше 30 минут, паттерн не закреплён: вернитесь к соответствующему модулю курса.

🧩 Quiz

1. Задача: «минимальная вместимость корабля, чтобы за D дней перевезти все грузы». Какой паттерн?
2. В условии: «сетка, из левого верхнего угла в правый нижний, шагов минимум» (без весов). Какой паттерн?
3. Задача: «самая длинная возрастающая подпоследовательность». Что верно?
4. Чем плох режим «триста задач подряд без разбора паттернов»?
5. «Все уникальные комбинации кандидатов с суммой target» — что выбираем?

✅ Итоги модуля

  • Паттерн — связка «признак условия → структура решения»; учить нужно признаки, а не задачи.
  • Каталог курса: 26 паттернов от двух указателей до modpow — таблица §20.1 плюс ваш личный каталог из практики.
  • Процесс решения из пяти шагов важнее скорости печати: классификация паттерна — первые пять минут любой задачи.
  • План тренировок: 8 недель по модулям, 30 минут на задачу, повторение слабых мест, журнал ошибок.

🔗 Куда дальше

Курс закончился, библиотека — нет. У вас на руках: 20 модулей реализаций, собственные структуры (куча, хеш-таблица, trie, BST), три шаблона-заготовки и каталог паттернов. Что делать со всем этим дальше:

  • Тренируйте по плану §20.5 — первые две недели по каталогу, дальше «слепые» задачи без тегов: узнавание важнее решения.
  • Двигайтесь к продвинутым темам, когда база устоится: сегментное дерево и дерево Фенвика, суффиксный автомат, потоки и паросочетания, сжатие путей в DP. Все они — надстройки над этим курсом, не замена.
  • Применяйте в продукте: структуры вы теперь умеете выбирать осознанно — от top-K в метриках до DSU в дедупликации аккаунтов.

Хорошая остановка — пересобрать свой каталог паттернов через месяц: он должен заполняться быстрее и точнее, а не переписываться с нуля.