Тренировки по алгоритмам 5.0 Открытие Тренировок Лекция 1: Сложность, тестирование, особые случаи

YOUTUBE · 30.11.2025 03:50

Ключевые темы и таймкоды

Введение и цель курса

1:31
  • Михаил Густокашин преподает алгоритмы и структуры данных в ВШЭ.
  • Курс посвящен алгоритмическому собеседованию в Яндексе.
  • Цель курса - помочь подготовиться к собеседованию и улучшить навыки программирования.

Важность работающего и эффективного кода

2:26
  • Умение писать работающий код - ключевой навык.
  • Важно тестировать код и делать его эффективным.
  • В Яндексе требуется эффективный код для обработки больших объемов данных.

Тренировки и задачи

3:16
  • Тренировки будут включать маленькие алгоритмические задачи.
  • Код должен быть рабочим, протестированным и эффективным.
  • Время работы кода будет измеряться, и задачи не засчитаны, если не укладываются в лимиты.

Разнообразие кода и задачи

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

Сервисы для тренировки

6:06
  • Используются сервисы для тренировки, такие как Яндекс.Код и ЛитКод.
  • Эти сервисы помогают улучшить навыки и подготовиться к собеседованиям.
  • Курс учит подходить к решению задач, а не гарантирует успех на собеседовании.

Темы курса

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

Контесты и рейтинг

10:14
  • После каждой лекции будет доступен контест.
  • Задачи считаются зачтенными, если прошли все тесты и уложились в лимиты.
  • Рейтинг формируется по количеству решенных задач, а не по времени или качеству кода.

Бонусы и мотивация

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

Алгоритмическое собеседование

13:26
  • Будет проведен эфир с алгоритмическим собеседованием в Яндексе.
  • Участники увидят процесс собеседования в прямом эфире.
  • Для топ-200 участников будет организована персональная тренировка.

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

13:56
  • Участники будут изучать алгоритмы и готовиться к собеседованиям.
  • Тренировка поможет не только решать задачи, но и правильно вести себя на собеседовании.
  • Пробное алгоритмическое собеседование можно будет зачесть как настоящее.

Честность и результаты

14:53
  • Призывы к честности при решении задач.
  • Нечестные участники будут забанены.
  • Знания и умения останутся с участниками, даже если они не попадут в топ-200.

Введение в сложность алгоритмов

16:12
  • Лекции будут посвящены сложности алгоритмов и их тестированию.
  • Будут рассмотрены большие данные и эффективные алгоритмы.
  • Введение в RAM-машину и её упрощенную модель.

RAM-машина

17:12
  • RAM-машина упрощена для практических целей.
  • Доступ к памяти произвольный, операции с памятью и процессором выполняются за одну операцию.
  • Переходы и вызовы функций также считаются одной операцией.

Условности и критерии оценки

18:04
  • Условности в RAM-машине для упрощения оценки сложности.
  • Реальная сложность программы оценивается по другим критериям.
  • RAM-машина похожа на выполнение программ на компьютере, но с упрощениями.

Введение в сложность алгоритма

19:13
  • Сложность алгоритма определяется количеством действий в зависимости от размера входных данных.
  • Пример: сортировка массива пузырьком требует n^2 действий.
  • Это простое определение сложности.

Аннотации и оценка сложности

20:08
  • Используется аннотация для структурирования информации.
  • Оценка функции сверху: алгоритм работает за O n^2.
  • Количество операций в RAM-машине можно вычислить явно, но это не всегда важно.

Применение теории на практике

21:06
  • Оценка сложности помогает понять, во сколько раз замедлится программа при увеличении данных.
  • Пример: программа, работающая за линейное время, замедлится в 10 раз при увеличении данных в 10 раз.
  • Важно понимать, во сколько раз замедлится программа, а не конкретные константы.

Пример с таблицей умножения

25:03
  • Программа для сложения таблицы умножения работает за O n^2.
  • Пример с более сложным кодом: сложность остается O n^2, несмотря на дополнительные действия.
  • Константы не важны, важно только, во сколько раз замедлится программа при увеличении данных.

Введение в сложность алгоритмов

27:33
  • В реальной жизни графики времени работы программы не всегда линейны.
  • Пример программы на Python, проверяющей наличие циклов в графе.
  • Создание массива и чтение данных через стандартные потоки ввода-вывода.

Универсальность ввода-вывода

28:30
  • Ввод данных через стандартные потоки позволяет поддерживать разные языки программирования.
  • Это может быть неудобно, но позволяет использовать любимые языки.
  • Создание массива и чтение числа с консоли не зависят от размера входных данных.

Чтение матрицы смежности

29:25
  • Чтение матрицы смежности графа требует n^2 операций.
  • Чтение строки длиной n занимает n^2 действий.
  • Вложенные циклы и элементарные операции увеличивают сложность до n^3.

Разные сложности частей программы

31:17
  • Программа имеет четыре разные сложности: n^1, n^2, n^3 и n^4.
  • При росте данных разные части программы замедляются по-разному.
  • Чтение данных и создание массива имеют большую константу, что замедляет работу.

Оценка сложности алгоритма

33:13
  • При больших значениях n, даже простые операции могут занимать много времени.
  • Алгоритм оценивается по самой медленной части, которая становится доминирующей при больших значениях.
  • Важно учитывать сложность алгоритма для его худшей части.

Пример задачи с разной сложностью

35:08
  • Задача: найти самый частый символ в строке с большим алфавитом.
  • Наивное решение: перебирать все символы и считать их количество.
  • Более умное решение: использовать множество всех символов строки для ускорения.

Ускорение алгоритма

38:31
  • Перебор всех символов можно ускорить, используя множество всех символов строки.
  • Это уменьшает сложность алгоритма до n^m, где m - размер алфавита.
  • Современные языки программирования позволяют ускорить процесс до нескольких секунд.

Введение в анализ текста

40:17
  • Обсуждение длины строки и размера алфавита.
  • Пример с текстом "Война и мир", где размер алфавита оценивается в 100 символов.
  • Ускорение анализа текста за счет использования множества символов.

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

41:11
  • Создание словаря для подсчета количества вхождений каждого символа.
  • Пример кода на Python для подсчета символов и нахождения самого частого символа.
  • Объяснение логики работы с символами и словарем.

Оптимизация кода

44:15
  • Обсуждение возможности вынести подсчет символов из цикла.
  • Сравнение эффективности различных подходов к оптимизации.
  • Важность учета времени и памяти при анализе алгоритмов.

Оценка сложности и памяти

46:37
  • Обсуждение сложности алгоритма и его симтотики.
  • Важность учета потребления памяти при анализе алгоритмов.
  • Пример сравнения алгоритмов по времени работы и потреблению памяти.

Заключение

50:08
  • Обсуждение различных подходов к реализации алгоритма.
  • Пример реализации алгоритма с использованием строки по байтам.
  • Подведение итогов и важность учета всех аспектов при анализе алгоритмов.

Преобразование строки в множество

50:21
  • Для преобразования строки в множество требуется вся строка.
  • Множество занимает порядка k элементов, где k всегда меньше или равно n.
  • Потребление памяти: n + k, где n - длина строки, k - размер множества.

Обработка строки посимвольно

51:20
  • В некоторых случаях строку можно обрабатывать посимвольно.
  • Это полезно, когда данные поступают по сети или в буфер.
  • Алгоритм позволяет обрабатывать данные на месте, не сохраняя всю строку в памяти.

Преимущества по памяти и сложности

52:20
  • Алгоритм эффективен по времени и памяти.
  • Он не сложнее предыдущих алгоритмов и может быть реализован с комментариями и нормальными названиями переменных.
  • Хороший алгоритм не всегда сложнее, чем неэффективный.

Сумма последовательности

54:03
  • Задача о сумме последовательности решается без запоминания всей последовательности.
  • Достаточно помнить накопленную сумму.
  • Алгоритм обрабатывает пустой массив и выводит ноль.

Поиск максимального числа

55:54
  • Задача о поиске максимального числа в последовательности.
  • Алгоритм должен учитывать возможность отрицательных чисел.
  • Решение: инициализировать максимум первым числом и заменять его при необходимости.

Обработка частных случаев

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

Проверка кода

59:35
  • Проверьте тесты из условия задачи.
  • Убедитесь, что код работает на примерах.
  • Выводите только то, что требуется в формате ввода и вывода.

Общий и особые случаи

1:00:20
  • Проверьте общий случай, чтобы убедиться, что программа работает.
  • Проверьте особые случаи, такие как первый и последний элементы последовательности.
  • Учитывайте возможные ошибки, такие как плюс-минус один элемент.

Тестирование на особые случаи

1:01:20
  • Проверьте, как программа работает с одинаковыми элементами и пустой последовательностью.
  • Учитывайте случаи, когда все числа отрицательные.
  • Убедитесь, что программа работает за линейное время.

План тестирования

1:03:08
  • Составьте план тестирования, учитывая все возможные случаи.
  • Проверьте, что программа работает на всех допустимых данных.
  • Учитывайте ошибки на плюс-минус один элемент и пустые последовательности.

Порядок действий

1:04:30
  • Сначала решите примеры на бумажке, чтобы убедиться в понимании задачи.
  • Составьте несколько примеров для лучшего понимания задачи.
  • Проверьте обработку пустой последовательности и последовательности из одного элемента.

Покрытие тестами

1:06:08
  • Проверьте краевые эффекты, такие как первый и последний элементы.
  • Убедитесь, что все ветки кода покрыты тестами.
  • Используйте маленькие тесты для быстрого нахождения ошибок.

Маленькие тесты

1:07:07
  • Маленькие тесты помогают быстро найти ошибку.
  • Один тест должен проверять одну ошибку.
  • Цель тестов – облегчить поиск места, где программа сломалась.

Тестирование программ

1:07:49
  • Создавайте тесты, где одна ошибка проявляется четко.
  • Разделяйте тесты на случаи с одним элементом и всеми отрицательными числами.
  • Это помогает быстрее найти и исправить ошибки.

Стресс-тестирование

1:08:48
  • В реальной разработке стресс-тестирование называется нагрузочным тестированием.
  • Важно рассчитывать время работы алгоритма до его написания.
  • На интерпретируемых языках можно рассчитывать на несколько десятков миллионов операций в секунду.

Генерация тестов

1:10:32
  • Генерируйте короткие тесты и запускайте их в вечном цикле.
  • Если ошибка есть, она проявится на маленьком тесте.
  • Длинные последовательности могут не дать результата.

Пример с сортировкой

1:11:32
  • В Python есть стандартная функция сортировки, которая помогает отловить ошибки.
  • Используйте стандартную функцию для сравнения с вашим кодом.
  • Если тест не проходит, отлаживайте по шагам.

Заключение

1:14:38
  • Эффективные решения часто бывают красивыми и понятными.
  • Пишите код, который можно читать и исправлять.
  • Понимание работы стандартных функций помогает в написании кода.
  • Не всегда нужно самое эффективное решение, иногда достаточно простого и работающего.
  • Тестирование кода должно быть приоритетом, чтобы избежать багов в промышленном коде.

Оценка сложности программ

1:19:13
  • Оценка сложности программ и алгоритмов - сложная тема, требующая докторских диссертаций.
  • В лекции будут рассмотрены примеры оценки сложности для сложных случаев.
  • Книги, такие как "Алгоритмы: построение и анализ", содержат главы о сложности алгоритмов.

Влияние оптимизации на производительность

1:20:08
  • Оптимизация кода влияет на константу, но не на симптоматику алгоритма.
  • В высоконагруженных сервисах важно знать, как язык оптимизирует код.
  • В учебных задачах важен не только худший случай, но и средняя скорость работы алгоритма.

Пример задачи с поиском самого частого символа

1:22:03
  • В худшем случае все буквы в тексте будут разными, что приведет к квадратичной сложности.
  • В реальной жизни важна средняя скорость работы алгоритма.
  • В задаче с текстом важно учитывать размер алфавита, который часто меньше длины текста.

Распределение рейтинга и задачи

1:23:28
  • Цель - найти человека, который решит все 40 задач.
  • Важно решать как можно больше задач, но не переживать из-за рейтинга.
  • Главное - это знания и сохранение здоровья и хорошего настроения.

Дедлайны и тестирование

1:24:43
  • Дедлайны для задач наступают за час до разбора.
  • В тестирующей системе можно увидеть, на каком тесте программа дала неправильный ответ.
  • Для помощи в поиске ошибок создан бот, который выдает тесты и правильные ответы.

Методы оценки сложности

1:27:03
  • В практике чаще всего используется оценка сложности по большому.
  • Важно понимать, во сколько раз замедляется программа при увеличении параметров.
  • В первом примере сложность оценивается в квадрат, что объясняется упрощенно.

Оценка сложности кода

1:27:55
  • Оценка сложности кода зависит от количества посылок и штрафов.
  • Условия тестирования для разных языков программирования в основном одинаковые.
  • Python удобен для написания кода, но требует эффективности, в то время как C++ позволяет писать неэффективно, но неприятно.

Преимущества и недостатки языков

1:28:50
  • Python позволяет писать быстро и красиво, но требует эффективности.
  • C++ позволяет писать неэффективно, но всегда неприятно.
  • Другие языки программирования находятся между этими двумя крайностями.

Тестирование и оценка времени выполнения

1:29:50
  • Программа, работающая дольше одной секунды, считается завершенной.
  • Превышение времени выполнения не всегда означает, что программа работала неправильно.
  • Задачи по определению сложности кода помогают набить опыт.

Использование библиотек и сложность алгоритмов

1:30:47
  • В Яндекс.Контесте можно использовать стандартные библиотеки.
  • Обращение к элементу словаря в Python имеет линейную сложность.
  • Оценка сложности алгоритмов учитывает время на выделение памяти.

Вопросы и поддержка в чате

1:34:45
  • В чате в Telegram можно получить помощь от сотрудников Яндекса и других участников.
  • Важно формулировать вопросы четко и содержательно.
  • Комьюнити в чате помогает быстро получать ответы и решать проблемы.