Две суммы, Valid Parentheses и Merge Intervals — по три раза каждую, ещё до первого реального интервью. Не из любви к ним. Просто после пары недель паузы задача снова выглядит новой: смутное «где-то я это видел», а на экране опять брутфорс.
Количество задач тут ни при чём. Всё решается тем, что вы делаете с задачей после того, как она зачлась зелёной галочкой.
Счётчик решённых — плохой спидометр
150 решённых. 300. Цифра в профиле растёт и создаёт ощущение движения вперёд. На интервью спрашивают другое: узнаете ли вы форму задачи в первые пять минут, когда условие сформулировано иначе и знакомого названия нет.
Это вопрос воспроизведения по памяти, а не объёма. Четыреста задач, из которых вы под давлением не вытащите ни одной идеи, — это в основном практика чтения чужих решений.
Сто двадцать задач, про каждую из которых вы по памяти скажете «это скользящее окно, потому что…», полезнее. Спорить тут особо не о чем.
Сначала паттерны, потом раскладывание задач по ним
Большинство интервью-задач укладывается в небольшой набор форм: два указателя, скользящее окно, бинарный поиск по ответу, BFS и DFS по сеткам, топологическая сортировка, куча для top-k, интервалы, монотонный стек, union-find и семейства динамики вроде рюкзака и наибольшей общей подпоследовательности.
После решения задачи допишите одну строку: какой это паттерн и что именно в условии на него указало. Вторая половина важнее первой — в интервью новая задача не будет называться так же.
Longest Substring Without Repeating Characters: скользящее окно. Подсказка: «самый длинный непрерывный» плюс ограничение, которое отслеживается через set.
Записывайте «почему», код не переписывайте
Старые заметки со вставленными решениями — мёртвый груз. Вы их не перечитываете. А если перечитываете, киваете и не учитесь ничему: читать код, который уже понятен, — самая низкоусиленная форма ревизии из возможных.
Лучше держать для каждой задачи свои формулировки:
- паттерн и подсказка в условии;
- тот единственный инсайт, после которого щёлкнуло. Для Trapping Rain Water это «вода в каждой точке зависит от меньшего из максимумов слева и справа»;
- своя первая ошибка: съехал на единицу при сжатии окна, забыл пустой ввод — что было, то и пишите.
Слов на сорок. Код и так лежит на LeetCode.
Перерешивать, а не перечитывать
Вот что реально сдвинуло цифры. Через несколько дней после решения — заново, в пустом редакторе, без подглядываний в прошлую отправку.
Иногда пролетаете. Иногда застреваете ровно в том же месте, и это диагноз: вы запомнили ответ, а не идею. В любом случае десять минут вместо сорока, которые ушли на первое решение.
По сути это активное припоминание, только применённое к коду. Достать из памяти — то, что заставляет остаться. Посмотреть ещё раз — почти ничего не даёт.
Разведите повторения по времени
Перерешать следующим утром — слишком легко, время потрачено зря. Через два месяца — начинаете с нуля.
Работает интервальное повторение: через день, потом через несколько дней, потом через неделю, две, месяц. Каждое успешное повторение отодвигает следующее. То, что снова не получилось, возвращается раньше остальных. Логику SM-2 можно реализовать самому — по сути это две даты на задачу.
Хватит таблицы с колонками «когда смотрел в последний раз» и «когда смотреть снова». Или Anki с одной карточкой на подсказку паттерна. Инструмент вторичен, а вот приходить на повторения — обязательно.
Объяснения, которые вы смотрели, тоже надо вернуть в оборот
Часть знания паттернов приходит вообще не с LeetCode. Из разбора NeetCode про то, почему бинарный поиск работает по отсортированному пространству ответов. Из двенадцатиминутного видео про union-find со сжатием путей. Из статьи, после которой наконец стало понятно bottom-up ДП.
Всё это сохраняется в закладки и больше не открывается. Автор исходного текста сделал под эту дырку приложение Recl: кидаешь туда видео, рилс, подкаст или статью, оно делает выжимку главных идей с таймстемпами, раскладывает по темам и поднимает их обратно на 1, 3, 7, 14, 30 и 60-й день после сохранения. Плюс поиск по своим сохранениям в виде вопроса — «что у меня было про монотонные стеки».
Волшебства внутри нет: задачи оно не решает и трекером LeetCode не является. Перерешивание в пустом редакторе всё равно на вас.
Гринд против работы с паттернами
| Критерий | Бесконечный гринд | Паттерны и повторения |
|---|---|---|
| Метрика прогресса | Количество решённых задач в профиле | Узнавание формы новой задачи за первые пять минут |
| Что делаете после решения | Ставите галочку и переходите к следующей | Одна строка про паттерн, подсказку, инсайт и первую ошибку |
| Что происходит через пару недель | Задача выглядит совершенно новой | Помните подход, спотыкаетесь на деталях реализации |
| Сколько времени на задачу | Каждое возвращение стоит как первое решение — около сорока минут | Повторение съедает десять-пятнадцать минут |
| Скорость роста счётчика | Быстро | Заметно медленнее |
Неделя, которая работает
- Две-три новые задачи в день, выбранные по паттерну.
- К каждой — заметка: паттерн, инсайт, первая ошибка.
- Десять-пятнадцать минут на перерешивание того, что подошло по расписанию.
- Любой хороший разбор — туда, откуда он вернётся сам.
Где обычно ломается
Счётчик как единственная метрика. Тогда пропуск повторения не считается потерей, а ведь именно он и есть потеря.
Заметки-копипаста. Код в них не перечитывают, а если перечитывают, то без пользы.
Повтор не в ту сторону. Слишком рано — легко и бессмысленно, слишком поздно — с чистого листа.
Коллекция объяснений без возврата. Плейлист с разборами union-find сам себя не откроет.
Не записана первая ошибка. А повторяется обычно именно она.
Счётчик решённых растёт медленнее, чем раньше. Зато когда попадается задача про самое длинное окно с не более чем k разными символами, вы понимаете, что это, не дочитав условие до конца. Из всех чисел на собеседовании учитывают только это.
Комментарии (0)
Войдите, чтобы комментировать.
Пока нет комментариев. Будьте первым.