Как научиться решать алгоритмические задачи по программированию
Перейти к содержимому

Как научиться решать алгоритмические задачи по программированию

  • автор:

Как научиться быстро решать задачи.Советы, литереатура?

Как решать подобные задачи по графике?
Вот собственно говоря задание: Я что-то вообще не могу понять, как выполнять это задание. Считать.

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

Помогите решать задачи
Даны натуральные числа m и n. Найти такие числа m1 и n1, не имеющие общих делителей, что m1/n1=m/n.

Кто учится решать задачи?
Добрый день, Господа. Я начал учить алгоритмы и учиться решать задачи по программированию. Если.

Грокаем алгоритмы: Гайд по алгоритмам для тех, кому сложно решать задачи

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

Эта статья — для разработчиков, которые частично уже знают алгоритмы. Если вы еще не знакомы с ними, советуем пройти трек «Алгоритмы и структуры данных» на Хекслете. Вы изучите списки, стеки, очереди, структуры данных, которые помогут проектировать структуры и алгоритмы.

Грокать алгоритмы или не грокать? Что делать, если вам не хочется решать сто задач к вашему следующему собеседованию?

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

Несмотря на это, я люблю алгоритмы и люблю решать задачки по программированию. Для меня это веселое времяпровождение и хорошая тренировка для мозга. Учитывая все это, хочу рассказать вам о моей собственной технике подготовки к собеседованиям, которая намного интереснее и волнительнее, чем обычная подготовка.

Коротко расскажу о себе, чтобы вы убедились в моей экспертности. Я программирую уже 20 лет, за это время я много раз менял место работы. Всего я прошел около 30 воронок найма — больше 120 собеседований. Плюс к этому у меня есть опыт с той стороны баррикад: я провел около 300 технических собеседований и больше 200 собеседований по системному дизайну.

Где мы грокаем алгоритмы

Если вы когда-нибудь искали работу, то знаете, что есть ресурсы, которые собирают задачи с собеседований. Один из них — LeetCode, это самый популярный сайт, где очень много задач. Плюс вокруг него сложилось развитое сообщество, где можно обсуждать задачки с другими инженерами. Если выдается свободная минутка, я всегда не прочь провести ее на LeetCode. Там я решаю задачи или читаю чужие решения, после чего сравниваю со своими.

Самая большая проблема LeetCode в том, что сайту не хватает продуманной системы обучения. У него много разных задач, в которых легко потеряться. Сколько нужно таких задач, чтобы подготовиться к собеседованию? Я бы предпочел двигаться по продуманной программе, в конце которой я смогу ощутить уверенность в собственных знаниях. Но системы нет, а я ленивый, и вообще — не хочу решать 500+ задач.

Одно из популярных решений для этой проблемы — решать задачи, которые относятся к одной структуре данных (например, прорешать несколько задач с деревьями). Какая-то система обучения появляется, но это решение меня все равно не устраивает. Например, что делать, если задачу можно решить при помощи разных структур данных?

Какую систему обучения придумал я

Я бы предпочел такую систему, в которой задачи распределены по паттернам, а не по структурам данных. Мои любимые паттерны — скользящее окно, нахождение цикла и топологическая сортировка. Когда я научился пользоваться этими методами, я стал решать незнакомые задачи по аналогии с задачами, которые решал до этого. Благодаря этому весь процесс подготовки к собеседованиям стал более интересным и веселым. Ну и конечно же, более систематичным.

Я обнаружил 25 паттернов, которые лежат в основе решения большинства задач. Думаю, эти паттерны помогут кому угодно показывать на собеседованиях красивые и элегантные решения. Вся фишка этих паттернов в том, что понимая один из них, вы научитесь решать сразу несколько задач, десятки задач.

Самые распространенные паттерны для решения задач

Читайте также: Это снова я, резиновая уточка: что такое метод Фейнмана и почему с его помощью так просто изучать программирование

Метод скользящего окна

Контекст: Мы используем этот метод, когда у нас есть входные данные с заданным размером окна.

Задачи для этого паттерна:

Метод двух указателей

Контекст: Мы используем два указателя, чтобы перебрать все входные данные. Обычно два указателя движутся в противоположных направлениях с фиксированным интервалом.

Задачи для этого паттерна:

Нахождение цикла

Контекст: Еще этот алгоритм называют алгоритмом черепахи и зайца. В отличие от предыдущего метода, два указателя тут движутся с разной скоростью.

Задачи для этого паттерна:

Интервальное слияние

Контекст: Этот метод применяют, если есть пересекающиеся интервалы. Например, на этом изображении мы видим, что интервалы a и b могут пересекаться шестью разными способами:

Задачи для этого паттерна:

Цикличная сортировка

Контекст: Если входные данные лежат в заданном интервале, используйте цикличную сортировку.

Задачи для этого паттерна:

In-place Reversal для LinkedList

Техника: Эта техника описывает эффективный способ перевернуть связи между узлами в LinkedList (класс Java). Часто мы ограничены in-place, то есть мы должны использовать исходные узлы.

Задачи для этого паттерна:

Поиск в ширину

Контекст: Это метод для решения задач с деревьями.

Задачи для этого паттерна:

Поиск в глубину

Контекст: Тот же, что для предыдущего метода.

Задачи для этого паттерна:

Двоичная куча

Контекст: Во многих задачах у нас есть набор элементов, который можно разделить на две части. Тогда мы могли бы выяснить, какой элемент является наименьшим в первой куче и какой является наибольшим во второй куче.

Задачи для этого паттерна:

Подмножества

Контекст: Если задача требует перестановки или комбинаций элементов, используйте подмножества.

Задачи для этого паттерна:

Усовершенствованный бинарный поиск

Контекст: Эта техника использует логический оператор для наиболее эффективного поиска элементов.

Задачи для этого паттерна:

Наибольшее K элементов

Контекст: Эта техника используется, чтобы найти наибольший/наименьший или наиболее часто встречающийся набор k-элементов в коллекции.

Задачи для этого паттерна:

Читайте также: Как решить задачу, если непонятно, с чего вообще начать: советы от Хекслета

K-образное слияние

Контекст: Используйте эту технику, если у вас есть список отсортированных массивов.

Задачи для этого паттерна:

Рюкзак 0-1

Контекст: Этот паттерн используют для задач на оптимизацию. Используйте эту технику, чтобы выбирать элементы, которые дают максимум выгоды в данном наборе ограничений по вместимости. Учитывая то, что каждый элемент может быть выбран лишь единожды.

Задачи для этого паттерна:

Неограниченный рюкзак

Контекст: То же самое, что в предыдущем паттерне, но только каждый элемент может быть выбран повторно сколько угодно раз.

Задачи для этого паттерна:

Числа Фибоначчи

Контекст: Как очевидно из названия, это паттерн для чисел Фибоначчи. Это последовательность, в которой каждое последующее число равно сумме двух предыдущих чисел.

Задачи для этого паттерна:

Наибольшая последовательность — палиндром

Контекст: Имеется в виду задача, которая может быть использована как для последовательности, так и для строк. По сути это задача на оптимизацию.

Задачи для этого паттерна:

Наибольшая общая подстрока

Контекст: Как понятно из названия, это паттерн для работы со строками или другими последовательностями, а также для работы с наборами строк или последовательностей.

Задачи для этого паттерна:

Чтение префиксного дерева

Контекст: Это специфичная для структуры данных техника, с помощью которой читают или создают префиксное дерево.

Задачи для этого паттерна:

Острова в матрице

Контекст: Этот паттерн подходит для чтения любого двумерного массива, где нам нужно обнаружить связанные между собой элементы.

Задачи для этого паттерна:

Путь проб и ошибок

Контекст: Этот паттерн подойдет для того, чтобы пройтись по массиву в поисках подходящего под требования элемента.

Задачи для этого паттерна:

https://amdy.su/wp-admin/options-general.php?page=ad-inserter.php#tab-8

Система непересекающихся множеств

Контекст: Если данные раскиданы по непересекающимся множествам, то они решаются одним и тем же способом.

Задачи для этого паттерна:

Поиск уникального маршрута

Контекст: Этот паттерн подойдет для прохождения по любому многомерному массиву.

Задачи для этого паттерна:

Продолжайте учиться: На Хекслете есть несколько больших профессий, интенсивов и треков для джуниоров, мидлов и даже сеньоров: они позволят не только узнать новые технологии, но и прокачать уже существующие навыки

Готовимся к алгоритмическому big-tech интервью: язык имеет значение

Решение алгоритмических задач программирования на доске или в веб-редакторе — стандартный этап прохождения интервью во всех крупных западных и некоторых российских компаниях. О том, как научиться решать задачи, написано много книг. Например, в самой популярной из них «Cracking the Coding Interview» вы найдете много полезных советов, а веб-ресурсы, такие как Leetcode, дадут возможность потренироваться в решении и обсуждении их. Поэтому в данной статье я не буду давать рекомендации об этом, а хочу поговорить о том, какое практическое значение имеет язык программирования при прохождении интервью. Многие компании дают на выбор несколько языков, а некоторые говорят «решайте на любом, главное — грамотно».

О пользе алгоритмических интервью ходят споры. Есть те, кто их не любит и считает неэффективными. С этим можно соглашаться или нет, но оставим дискуссии за рамками. Я не могу повлиять на систему проведения интервью, но могу помочь справиться с ними.

Обо мне

Сейчас я работаю в одной из компаний МААНГ. В процессе трудоустройства я прошел не один раунд, несколько итераций, успел побывать в разных компаниях и мог сравнить это на своем опыте. Мой профиль на Leetcode не самый завораживающий, но его хватило при условии, что я не решал алгоритмические задачки до этого совсем.

Почему мой любимый / основной язык не всегда самый лучший?

При выборе языка большинство скажет: «Конечно же, мой любимый язык Ч» или «Тот, который я знаю лучше всего». Это имеет смысл: интервью — это стресс, и хочется полагаться на наиболее знакомый и проверенный инструмент. Однако, как и любой инструмент, он может лучше подходить для одних задач и хуже для других. В целом, я бы свел критерий, когда стоит менять язык под задачу, к следующему алгоритму:

Приведу пример из личного опыта. Я люблю Golang и несколько лет назад, когда я только начинал решать задачи, я решил использовать его. Однако, во всех задачах, где требовалось реализовать очередь, стек или вычислить min/max, мне приходилось писать свою реализацию. Да, это не сложно, но требует фокуса и немного времени. В итоге, я даже собрал свой GitHub репозиторий (только для любопытных), но получалось не складно. Поэтому спустя некоторое время я решил подобрать язык, который бы вызывал у меня минимум проблем при достижении цели. Все же решение алгоритмических задач сильно отличается от продуктовой разработки. Вам не требуется многопоточность и вся мощь ООП, достаточно читабельного, понятного кода, который будет работать с хорошей алгоритмической сложностью.

Критерии выбора

Давайте разберем по порядку, что означает критерий «решение алгоритмических задач на интервью».

Алгоритмическое интервью это:

Интервью где вам за короткое время необходимо решить алгоритмическую задачу.

Время на решение задачи варьируется от 15 до 30 минут, в зависимости от компании и сложности.

В ходе решения вам необходимо выяснить все исходные данные, частные случаи и условия (часто задача дана просто заголовком), придумать решение, написать его, протестировать и внести исправления.

Интервью обычно проходит с живым человеком, с которым необходимо активно общаться: получать те самые данные, объяснять свои действия и рассказывать пошагово, как работает программа. Наилучшей практикой считается возможность писать и говорить одновременно, но можно и последовательно.

Использование продвинутых итераторов считается не самой лучшей практикой (list comprehension, LINQ, лямбды и т.д.), читать и разбирать такой код сложнее. Почти в любом языке есть возможность написать программу в 1 строчку. Разобрать это сможет только эксперт этого языка, ваш интервьюер может таковым не быть.

Если интервью проходит онлайн, писать предстоит в веб-редакторе (с подсветкой синтаксиса, но без подсказок), а если лично, то зачастую на доске.

Код не всегда просят компилировать, часто необходимо доказать интервьюеру, что решение будет работать.

Алгоритмическая задача это:

Задача в которой необходимо обработать входную информацию и дать ответ (т.е. реализовать функцию)

Знания, для имплементации грубо сводятся к стандартным знаниям программирования, регулярно требуется применение структур данных из стандартных библиотек. Т.е. использование очередей, стеков, связных списков это нормальная практика.

Иногда требуется реализовать класс с набором определенных функций или использовать вспомогательный класс. Тогда подразумевается использование ООП и без него крайне трудно обойтись. Несмотря на абстрагированность от языка, ряд задач имеют ООП бэкграунд.

Использование сложных задач, написание именных алгоритмов, dynamic programming встречается крайне редко и вас скорее всего заранее предупредят, если таковое может быть.

Допускается, что если код не требует компиляции и какой-то структуры данных нет в стандартной библиотеке, то ее можно просто озвучить, как будто она есть и не писать. Тут есть «но» и «если», поэтому спокойнее, если она все же есть.

Итого, мы имеем мало времени и кучу стресса, поэтому все вышеописанное в отношении выбора можно свести к:

Минимизация времени написания кода (т.е. меньше символов и лаконичнее синтаксис).

Легко читаемый код, не сокращенный с помощью сложных итераторов.

Наличие стандартных контейнеров и поддержка ООП должны быть.

Сравнение на задаче

Давайте сравним решение одной и той же задачи, реализованное на разных языках. В качестве примера возьмем популярную задачу “Валидация скобочной последовательности” (Valid parentheses):

Дана строка, которая состоит из круглых, фигурных и квадратных скобок. Нужно определить, является ли скобочная последовательность верной. Строка является верной, если:

1) Открытая скобка закрыта скобкой такого же типа.
2) Все скобки закрыты в верном порядке.

Допущения:
1) В строке встречаются только следующие скобки: ‘()[]<>‘.
2) Строка вмещается в память

Python

JavaScript

C++: ведет себя довольно лаконично, имеет богатейшую коллекцию стандартных контейнеров, что требует дополнительных навыков для грамотного их применения. 286 символов.

Java: имеет тяжелый синтаксис инициализации и длинные названия встроенных функций. 406 символов.

С#: так же длинные названия встроенных функций и требует много места, поскольку принято переносить открывающую скобку на новую строку. 321 символ.

Python: наиболее лаконичен, даже при наличии типизации функции, краткая и довольно понятная нотация, множество встроенных функций. 219 символов.

JavaScript: версия решения несколько отличается, но она все равно краткая, есть все функции, хотелось бы иметь хотя бы типизированную сигнатуру функции. 240 символов.

Go: в языке приняты краткие названия переменных, что сильно экономит время когда их надо полностью печатать, нотация также короткая, но реализация стека портит картину. 393 символов со стеком или 231 символов если считать что стек реализован.

Разбор одной задачи не является статистикой, поэтому вы можете продолжить сравнение. Я же старался подобрать такую задачу, которая могла бы выступить собирательным образом и отразить спектр нюансов, которые вносит язык.

По всем критериям победителем для меня стал Python. Я никогда не был его фанатом, поскольку для решения рабочих задач предпочитаю типизированные языки с хорошей многопоточностью, но в ситуации, когда задачу нужно решать на время, минимизировать ошибки и ментальную нагрузку, Python’у равных я не нашел.

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

Заключение

Есть ситуации, когда имеет смысл сменить свой привычный язык на тот, который позволит решать вам задачи быстрее и освоить его до уровня интервью может оказаться проще чем вы думаете. Для качественной подготовки вам все равно предстоит решить как минимум 50-100 задач, за это время язык вполне можно освоить.

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

Как правильно решать задачи на LeetCode: подробный гайд по тренажёру для программистов

Нина Торгунакова из «Злых марсиан» за год нащёлкала 400 алгоритмических задач и рассказала, как извлечь из этого занятия максимальную пользу.

Фото: Getty Images

Мария Даровская

Нина Торгунакова

Фронтенд-разработчик в «Злых марсианах», любит спорт и pole dance, ведёт канал strip_programmer. КМС по пулевой стрельбе, переводит статьи о разработке, LeetCode warrior.

Ссылки

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

Тем не менее большинство пришедших на платформу забрасывают занятия уже через неделю — подобная статистика есть, например, на ежегодном Advent of Code. Я же решала задачи на LeetCode больше года — получила неимоверное удовольствие, прокачала важные навыки. Вот как это было.

Зачем мне понадобился LeetCode

Идея попробовать LeetCode время от времени появлялась у меня ещё с университета: мне всегда нравились алгоритмы. Но в полноценное, осознанное желание она переросла осенью 2021 года. Для решения одной из рабочих задач потребовались операции с хеш-таблицами, и я поняла, что слишком долго думаю, как обработать структуру данных. Следовательно, решила я, в моих познаниях есть определённые пробелы, которые нужно восполнить.

С таким настроем я и приступила к челленджу: в течение целого года практически ежедневно разбирала минимум по одному примеру из LeetCode. С тех пор их количество перевалило за четыре сотни.

Я хотела, чтобы это вошло в привычку, так что правило «один день — одна задачка» старалась соблюдать неукоснительно. Если вдруг по каким-то причинам сделать это не получалось — всегда навёрстывала отставание в следующие дни.

Постепенно втянулась, поняла, что пользы от LeetCode гораздо больше, чем я изначально предполагала, и даже описала свой опыт в треде в Twitter, на который меня вдохновили коллеги из «Злых марсиан» и особенно Андрей Ситник. В частности, я попыталась развенчать расхожий миф, что такие задачки годятся только для подготовки к собеседованию.

На самом деле это лишь вершина айсберга. Подобная практика в первую очередь тренирует скорость, с которой вы соображаете, когда пишете код. А ещё позволяет правильно формулировать уточняющие вопросы заказчикам и коллегам. Мне кажется, многим из нас не хватает этого навыка.

В IT-среде часто ругают LeetCode: мол, всё равно в реальной работе кейсы оттуда не встречаются, само по себе знание алгоритмов не помогает писать хороший код, а незнание — плохой и так далее.

Но ведь LeetCode — это просто инструмент: он не плохой и не хороший, не полезный и не вредный. Всё зависит от того, как вы будете его использовать.

Как работать с LeetCode

Первым делом советую заглянуть в Beginner’s Guide в разделе Explore — там подробно объясняется, как всё устроено на сайте и с чего лучше всего начать.

У каждой задачи есть свой уровень: лёгкий, средний или сложный. Чтобы правильно подобрать уровень по себе, нужно понимать, в каких темах вы более-менее сильны, а в каких совсем плаваете.

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

Чтобы увеличить сложность решаемой задачи, полезно не только повышать уровень (например, с easy переходить на medium), но и понижать acceptance задачи, то есть процент её принятия. Он позволяет понять соотношение правильных решений ко всем отправленным.

В некоторых случаях этот параметр даже более показателен, чем уровень сложности. Действительно, некоторые формально «средние» задания на практике может одолеть меньше пользователей, чем формально «хардовые».

В разделе Explore можно найти также курс по каждой теме, внутри которого уровень задач нарастает постепенно. Как только я открыла для себя эту фичу, стала придерживаться именно такого порядка.

Но после создания аккаунта на LeetCode можно остаться и в разделе All. В нём над кнопками All topics, Algorithms, Database есть хештеги, их можно развернуть и посмотреть количество задач в каждом из них.

Необязательно хватать сразу весь топик. Лучше отфильтровать задачи по хештегам, например Sorting или String, и затем отсортировать по возрастанию сложности.

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

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

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

А в разделе All очень просто отыскать самые лёгкие задачи для старта. Там есть удобная сортировка: сначала по сложности, потом по acceptance. Всё, что окажется вверху, — это и есть начальный уровень.

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

Рекомендую идти по порядку, начиная с простых задач. Сперва смотрите объяснения — что это за структура или концепция, на чём она основана. Прочтите материалы, а потом начинайте решать. Когда справитесь с первой лёгкой задачей, можете считать, что примерно поняли принцип, по которому надо работать с такими структурами. Но не останавливайтесь на этом, обязательно повышайте уровень сложности.

Если решаете все лёгкие задачи и большую часть средних, то можете спокойно переходить к другой теме. Останавливаться на сложных задачах необязательно. Они могут потребовать много времени и концентрации, но, по статистике, на собеседованиях их попадётся не больше 20%. Даже продвинутые компании обычно берут задачи medium-уровня — про это хорошо написано на сайте Leetcode Therapy.

Я не считаю, что уровень hard бесполезен. Но для базового понимания разных структур и алгоритмов среднего будет достаточно. Если захочется углубиться, то задачи со звёздочкой можно будет порешать позже.

Как не надо решать задачи

Самая типичная ошибка: многие сразу начинают решать так называемые задачи дня, Daily LeetCoding Challenge. Такая задача всегда закреплена первой в общей таблице. Но брать их я рекомендую, только если ваша алгоритмическая подготовка уже на очень хорошем уровне. Я сама клюнула на удочку после нескольких месяцев тренировок — и это был самый непродуктивный период за всё время обучения. Иногда таски попадались настолько сложные, что их решение затягивалось на часы, а это совершенно непродуктивно.

Дело в том, что Daily LeetCoding Challenge, как и следует из названия, — скорее состязание, чем обучение. Поэтому решать daily-задачи без хорошего бэкграунда вредно для психики и скорее только приведёт к выгоранию. Оно вам надо?

Ещё больший мазохизм для новичка — перейти в раздел Contest, где вам отведут час на три задачи. Причём соревноваться с вами будут профессиональные спортивные программисты из Китая, которые за одну минуту решают что угодно. Это самый верный способ потерять веру в себя, поэтому идти туда нужно очень подготовленным.

Как надо решать задачи

Лайфхак №1: при чтении условия сразу думайте о граничных случаях. Проанализируйте, как ограничения, перечисленные в задаче, могут повлиять на алгоритм. Переберите в уме подходы, с помощью которых её можно решить. Так победите.

Лайфхак №2: долго сидеть над одной задачей — контрпродуктивно. Работа с LeetCode не предполагает больших и чересчур сложных решений. Это скорее маленькие таски, рассчитанные на максимум 100 строк, даже если вы пишете код на С++. Поэтому рекомендую посвящать LeetCode не больше 45–60 минут в день.

Лайфхак №3: если вы долго не можете нащупать решение — скорее всего, вы движетесь в неверном направлении. Это не страшно, я тоже иногда не могу что-то решить в течение получаса. В таком случае я перехожу в раздел Discuss и читаю, что пишут люди, которые работают на моём языке программирования. Почему задача может не решаться быстро? Проблем обычно бывает несколько.

Вы действительно не знаете решение и пошли по ложному пути. Тогда задачу лучше отложить и понять, что конкретно вы не знаете.

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

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

Совет: на LeetCode есть раздел «Подборки», куда можно добавить задачу, чтобы она не потерялась, и попытаться решить её позже. Соответствующая кнопка называется My List и отмечена в меню профиля сердечком или папкой со звёздочкой.

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

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

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

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

Вы начали с daily-задач. Некоторые переоценивают свои знания и сразу берутся за сложное. В общем, смотри раздел выше.

Совет: если всё-таки набрались смелости и решили попробовать свои силы в Daily, кликните на нужном дне в календаре справа в разделе All.

Как фиксировать свой прогресс

При решении задач желательно сразу писать код так, чтобы потом его было не стыдно показать другому программисту, — а ещё лучше действительно его показывать, выкладывая в раздел Discuss с объяснением.

Ваша оценка прогресса, скорее всего, будет очень нестабильна. Может случиться так, что, прорешав много лёгких задач на одну тему, вы переходите на средний или даже высокий уровень и всё получается. А в другой день попадается задача, усложнённая вопросом из незнакомой области, вы не можете её решить и расстраиваетесь. Или, переходя к другой теме и столкнувшись с трудностями, теряете веру в себя.

Если вы плохо ориентируетесь в какой-то теме и каждый раз допускаете ошибки, имеет смысл ей заниматься. Были разделы, в которых, даже если я один раз что-то одолела, решить аналогичную задачу уже не получалось. Например, самый тяжёлый топик для меня — динамическое программирование. Это не просто какой-то чёткий алгоритм или структура данных, подчиняющаяся правилам, это концепция, и нужно не только понимать и знать её, но и видеть, когда и как её можно применить в задачах.

Но всё равно: чем больше задач вы решаете и чем регулярнее это делаете, тем ощутимее растёт уровень знаний, ваша уверенность в себе и скорость, с которой вы пишете правильный код.

Если качество — это плавающий показатель, то рост скорости, с которой первично разбираешься в проблеме, можно отследить уже через пару месяцев. А если это простая тема вроде массивов, то ещё раньше, уже через пару недель.

Мне нравится, что LeetCode своеобразно поощряет постоянно решать задачи: монетками за «дейлики» или просто красивой статистикой в профиле. Конечно, такой мотивации вряд ли хватит, чтобы ломать голову, не сдаваясь ни на день, но это прекрасно работает как дополнительный стимул.

Один из моих знакомых сейчас пишет тред «365 дней с LeetCode», где каждый день делится прогрессом и рассказывает, какие задачи он решил. Спустя одну неделю после начала он подвёл итог: 13 задач. Уже на этом этапе он почувствовал, какие темы стал быстро решать сразу, а для каких надо подтянуть скиллы. И он в этом не одинок: мне стали чаще писать и делиться своим прогрессом люди, которые раньше совсем не решали задачи, но сейчас смогли начать. Кстати, рассказывать о своём успехе друзьям или просто читателям в соцсетях полезно: это помогает не сбиться с пути и найти новых единомышленников.

Как организовать своё время

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

Учитывайте уровень своей энергии в разное время суток

Например, как каждая уважающая себя сова, я с утра совсем не могу делать физические упражнения, но вечером с удовольствием занимаюсь спортом. А вот задачи мне легче всего решать на рассвете.

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

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

Нужно исходить из привычного вам ритма — только так получится сделать занятия регулярными. Это один из главных советов по самоорганизации.

Не тратьте слишком много времени на задачу

Не все задачи решаются с первого захода. Если решение не приходит в голову в течение 30–40 минут, почитайте дополнительную литературу и посмотрите чужие решения. Затем возвращайтесь к задаче.

Нет ничего зазорного в том, чтобы учиться у других и повторять их удачные приёмы. Это не поражение, а естественная часть обучения.

Помните: решение задач — это марафон, а не спринт

Прокачка знаний с помощью решения задач должно стать вашей долговременной целью. Если вы будете в течение недели решать по 20 задач в день, можно быстро перегореть и остановиться, а через месяц от приобретённых навыков ничего не останется. Поэтому регулярность очень важна. Не нужно набрасываться на задачи и пытаться решить всё, лучше выстроить стабильный процесс.

Итог: какую пользу приносит работа с LeetCode

Часто люди приходят на LeetCode, чтобы подготовиться к собеседованиям. Вы будете смеяться, но конкретно мне мой годовой опыт не пригодился: в последний раз, когда я искала новую работу, я проходила только через одно техническое собеседование (кстати, оно было к «Злым марсианам»), и оно было вообще не про решение алгоритмических задач в онлайн-формате. Тем не менее проведённый на LeetCode год помог мне почувствовать себя увереннее и пройти отбор. И вот почему:

  • Это расширило мой кругозор. Погуглить алгоритм и затем внедрить его — зачастую очень быстрый процесс. А вот понять, какой выбрать эффективный путь для решения задачи, — уже интереснее. Я уверена, что в реальной работе нам едва ли требуется полностью по памяти писать HeapSort, но иметь представление, что это и для чего, может быть полезно.
  • Научилась писать код более быстро и осознанно за счёт понимания сложности алгоритмов и разных структур данных, способности просчитывать граничные случаи и составлять сценарии для тестирования кода. Вспомните о ситуациях, когда вам попалась маленькая лёгкая задачка, но вы потратили на неё больше времени, потому что не довели до автоматизма написание нужных конструкций. У меня ощутимо выросла скорость работы на языке, на котором я решала всё это время, — на нём я и работаю. Какие-то вещи пишу на автомате и не боюсь задач, которые включают в себя такие структуры, как деревья, например.
  • Стала легче учиться новому. Я решала задачи на давно знакомом мне языке. Но знаю, что многие так практикуют язык, который ещё не знают. Это помогает в обучении, потому что, прежде чем подойти к рабочим задачам, как правило, нужно сориентироваться в синтаксисе. Тренировочные задачи помогают понять, когда вы можете уверенно решать что-то небольшое. Это важный этап перед тем, как перейти к серьёзным рабочим процессам.

Раньше я не всегда задумывалась о том, когда код может упасть, то есть каким может быть граничное тестовое значение, при котором что-то сломается или посчитается неправильно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *