Главная | Все статьи | Мотивация

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

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

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

Это адаптированный перевод статьи Grokking LeetCode: A Smarter Way to Prepare for Coding Interviews, автор — Арслан Ахмад. Повествование ведется от имени автора.

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

Бесплатные курсы по программированию в Хекслете
  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки
Выбрать курс

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

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

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

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

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

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

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

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

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

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

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

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

  1. Метод скользящего окна
  2. Метод двух указателей
  3. Нахождение цикла
  4. Интервальное слияние
  5. Цикличная сортировка
  6. In-place Reversal для LinkedList
  7. Поиск в ширину
  8. Поиск в глубину
  9. Двоичная куча
  10. Подмножества
  11. Усовершенствованный бинарный поиск
  12. Побитовое исключающее ИЛИ
  13. Top K Elements
  14. K-образное слияние
  15. Задача о рюкзаке 0-1
  16. Задача о неограниченном рюкзаке
  17. Числа Фибоначчи
  18. Наибольшая последовательность-палиндром
  19. Наибольшая общая подстрока
  20. Топологическая сортировка
  21. Чтение префиксного дерева
  22. Задача: количество островов в матрице
  23. Метод проб и ошибок
  24. Система непересекающихся множеств
  25. Задача: найти уникальные маршруты

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

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

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

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

  • Longest Substring with K Distinct Characters
  • Fruits into Baskets
  • Permutation in a String

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

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

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

  • Squaring a Sorted Array
  • Dutch National Flag Problem
  • Minimum Window Sort

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

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

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

  • Middle of the LinkedList
  • Happy Number
  • Cycle in a Circular Array

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

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

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

  • Intervals Intersection
  • Conflicting Appointments
  • Minimum Meeting Rooms

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

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

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

  • Find all Missing Numbers
  • Find all Duplicate Numbers
  • Find the First K Missing Positive Numbers

In-place Reversal для LinkedList

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

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

  • Reverse every K-element Sub-list
  • Rotate a LinkedList

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

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

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

  • Binary Tree Level Order Traversal
  • Minimum Depth of a Binary Tree
  • Connect Level Order Siblings

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

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

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

  • Path With Given Sequence
  • Count Paths for a Sum

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

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

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

  • Find the Median of a Number Stream
  • Next Interval

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

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

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

  • String Permutations by changing case
  • Unique Generalized Abbreviations

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

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

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

  • Two Single Numbers
  • Flip and Invert an Image

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

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

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

  • 'K' Closest Points to the Origin
  • Maximum Distinct Elements

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

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

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

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

  • Kth Smallest Number in M Sorted Lists
  • Kth Smallest Number in a Sorted Matrix

Рюкзак 0-1

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

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

  • Equal Subset Sum Partition
  • Minimum Subset Sum Difference

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

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

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

  • Rod Cutting
  • Coin Change

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

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

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

  • Staircase
  • House Thief

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

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

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

  • Longest Palindromic Subsequence
  • Minimum Deletions in a String to make it a Palindrome

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

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

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

  • Maximum Sum Increasing Subsequence
  • Edit Distance

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

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

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

  • Longest Word in Dictionary
  • Palindrome Pairs

Читайте также: Обзор на книгу «Грокаем алгоритмы» Адитья Бхаргава

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

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

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

  • Number of Distinct Islands
  • Maximum Area of Island

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

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

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

  • Find Kth Smallest Pair Distance
  • Minimize Max Distance to Gas Station

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

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

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

  • Number of Provinces
  • Bipartite Graph

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

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

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

  • Find Unique Paths
  • Dungeon Game

Бесплатные курсы по программированию в Хекслете
  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки
Выбрать курс

Аватар пользователя Lada Golunova
Lada Golunova 15 марта 2022
23
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 2 мая
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 2 мая
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 2 мая
профессия
от 5 840 ₽ в месяц
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 2 мая
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 2 мая
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 2 мая
профессия
Верстка с использованием последних стандартов CSS
5 месяцев
с нуля
Старт в любое время