Модуль 10 · Окно переменного размера · ОП.04

Алгоритмы на массивах · модуль 10 · окно переменного размера

Глава 10.10

10.10

Практика, шпаргалка
и домашнее задание

В этой главе работа на паре по стартовому набору lesson_10: четыре функции, 39 тестов и замер. Затем вопросы для контроля по КТП, шпаргалка, словарь модуля и домашнее задание: довести решения, найти три ошибки на границе окна и решить новую задачу с LeetCode. В конце — порядок сдачи и что будет на занятии 11.

Категория
Практика
Время на паре
Около 60 минут после 30 минут теории
Проверка
pytest, 39 тестов
Результат
Папка portfolio/lesson_10 с решениями, замером и заметкой

§1Стартовый набор

В архиве всё, что нужно для работы на паре и дома. Функции в solution.py пустые: в каждой стоит raise NotImplementedError, поэтому до начала работы все 39 тестов падают. Тесты границ из главы 10.6 в tests.py те же, к ним добавлены тесты задач и сравнение с перебором.

lesson_10/
solution.pyчетыре функции: схема прохода, две задачи КТП, расширение
tests.py39 публичных тестов pytest, среди них 14 тестов границ
bench.pyзамер окна против перебора, три опыта, глава 10.7
initial_attempt.txtвопросы к условию и примеры, записываются до кода
complexity_note.mdзаготовка заметки: состояние окна, условие while, инвариант, время, память, замер
task.mdусловия задач на пару
bugs_10.pyдомашнее задание: три функции с ошибкой на границе
tests_bugs_10.pyдомашнее задание: заготовки трёх тестов
homework_10.mdусловия домашнего задания
extra.pyдополнительные задачи: LeetCode 1004, 1493 и число подотрезков без повторов
tests_extra.py15 тестов к дополнительным задачам
Функция в solution.pyЗадачаГлава
longest_within0 · самый длинный отрезок в пределах лимита, схема прохода10.3
shortest_window1 · минимальный отрезок с суммой не меньше S, задача КТП10.4
longest_unique2 · подстрока без повторов, задача КТП10.5
total_fruitрасширение · LeetCode 90410.8

§2Порядок работы на паре

Работа идёт в папке lesson_10 на своём компьютере, нужен Python с pytest. Если Python ещё не настроен, начните с песочниц в главах 10.3–10.5: там те же функции пишутся прямо на странице и проверяются похожими тестами. Сдаётся всё равно solution.py с зелёным pytest.

  1. Скопируйте папку lesson_10 в portfolio/lesson_10/ личного репозитория и выполните python -m pytest tests.py -v. Все 39 тестов должны упасть: так проверяется, что pytest нашёл файлы и запустил тесты.
  2. До кода откройте initial_attempt.txt и запишите вопросы к условиям задач 1 и 2 и примеры с ответами: «отрезка нет», сумма точно равна s, пустая строка, повторы. Образец — глава 10.2.
  3. Напишите longest_within. Проверка: python -m pytest tests.py -k within.
  4. Напишите shortest_window. Проверка: -k shortest, затем тесты границ: -k "bad_s or shortest_edges". Если тест падает, найдите симптом в сводке главы 10.9, §1.
  5. Напишите longest_unique: -k unique.
  6. Запустите замер: python bench.py > bench_results.txt. Он идёт около 25 секунд.
  7. Заполните complexity_note.md для трёх обязательных функций.
  8. Если осталось время — total_fruit, -k fruit.
  9. Если и это готово — extra.py: единицы с заменой нулей, единицы после удаления, число подотрезков без повторов. Проверка: python -m pytest tests_extra.py -v.
На полях: когда можно открыть главы

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

§3Что сдаётся с пары

Работа на паре принята, когда

Схема прохода работаетpython -m pytest tests.py -k within — без падений.
Задачи КТП решены-k shortest, -k unique и тесты границ -k "bad_s or edges" — без падений.
Вопросы записаны до кодаВ initial_attempt.txt вопросы и примеры к обеим задачам.
Замер сохранёнbench_results.txt с выводом bench.py на своей машине.
Решение объясняетсяДля каждой задачи вы называете состояние окна, условие while и место записи ответа — контроль КТП.

§4Вопросы для контроля

В КТП контроль занятия записан так: «Кандидат объясняет условие while и состояние окна. Проверяются дубликаты и пустая строка». Ниже эти требования разложены на вопросы и на то, что должно прозвучать в ответе. Главы в правом столбце — где это разобрано.

ВопросЧто должно прозвучать в ответеГде разобрано
Что хранится в состоянии окна и как оно меняется?Сумма или частотная карта для окна с l по r; при расширении добавляется пришедший элемент, при сжатии убирается ушедший до сдвига l10.3, §4; 10.5, §3
Почему у цикла такое условие?Самый короткий отрезок — сжимаем, пока окно подходит; самый длинный — пока окно недопустимо. В задаче о подстроке достаточно проверить счётчик пришедшего символа10.4, §2; 10.5, §3
Зачем здесь цикл while?Одного сжатия может не хватить: на 'abba' версия с if возвращает 310.5, §7
Почему вложенный while не даёт O(n²)?l только растёт и не обгоняет r, сдвигов не больше 2n; свои числа из замера10.3, §5; 10.7
Какие тесты проверяют дубликаты и пустую строку?Все символы одинаковые, повтор рядом, повтор символа вне окна, пробел; пустая строка — 010.6, §5
Что функция делает, если отрезка нет, и при неверном пороге?Отрезка нет — 0, это обычный ответ; порог меньше 1 — ValueError10.6, §4

§5Шпаргалка по модулю

Самый длинный отрезокl = 0 for r in range(len(nums)): добавить nums[r] в состояние while окно недопустимо: убрать nums[l] из состояния l += 1 best = max(best, r - l + 1)

Ответ записывается после цикла: там окно допустимо. O(n).

Самый короткий отрезокfor r in range(len(nums)): total += nums[r] while total >= s: записать длину r - l + 1 total -= nums[l] l += 1

Ответ записывается внутри цикла: после цикла окно уже не подходит. best = 0 значит «отрезка нет».

Частотная картаcount[ch] = count.get(ch, 0) + 1 while count[ch] > 1: count[text[l]] -= 1 l += 1

Уменьшается счётчик символа на левой границе. Если условие считает ключи, len(count), ключ со счётчиком 0 удаляют.

Признаки в условии

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

Вопросы до кода

Бывают ли отрицательные числа. Что вернуть, если отрезка нет. Подходит ли сумма точно на пороге. Различается ли регистр, считается ли пробел символом. Может ли вход быть пустым.

Когда окно не подходит

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

Сложность и замер

Перебор — O(n²) в худшем случае, когда отрезка нет; на коротких ответах O(n·L). Окно — O(n) на любых данных. На 8000 элементах перебор медленнее в 4000 раз.

Типичные ошибки

Запись не в том месте относительно while. > вместо >=. if вместо while. l += 1 до вычитания. count[ch] -= 1. Нет проверки s < 1. Нет del при len(count).

§6Словарь модуля

ТерминЧто означаетГде введён
Окно переменного размераПравая граница идёт по списку, левая сдвигается вслед за ней, пока этого требует условие допустимости10.1
Условие допустимостиТребование задачи к отрезку, записанное как проверка за O(1) по состоянию окна10.1, 10.3
Расширение, сжатиеСдвиг правой границы с добавлением элемента в состояние; сдвиг левой с удалением элемента из состояния10.1, 10.3
Подходящее окноОкно, для которого выполнено условие задачи на самый короткий отрезок10.4
Частотная картаСловарь «значение → сколько раз оно встречается в окне»10.5
Граничный входВход на краю допустимого: пустой, из одного элемента, без ответа, с порогом точно на сумме10.6
Инвариант окнаСостояние соответствует границам окна, и после цикла окно допустимо (или уже не подходит, для самого короткого)10.3, §8
Монотонность границОбе границы двигаются только вправо; из неё следует O(n) для while внутри for10.3, §5

§7Домашнее задание

Максим Николаевич не хочет задавать домашнее задание. Но очень хочет

Человек с лицом манекена за столом с ноутбуками и монитором, подпись: «Праграмист»
ЗадачаЧто сделатьГде помогут
1 · Довести решенияsolution.py проходит все 39 тестов. bench_results.txt — ваш замер. complexity_note.md заполнен по трём функциям: состояние окна, условие while и откуда оно следует, инвариант, время, память и таблица замера.Главы 10.3–10.7
2 · Три ошибки на границеВ bugs_10.py функции max_ones, longest_k_distinct, shortest_at_least. Каждая верно отвечает на обычных входах и ошибается или падает на граничном. Для каждой: вход, на котором ответ неверный; падающий тест в tests_bugs_10.py; исправление одной строки; повторный прогон. Вывод pytest — в bugs_run.txt.Глава 10.6 и сводка ошибок в главе 10.9
3 · Отрезки с произведением меньше kФункция count_small_products(nums, k), LeetCode 713: сколько отрезков подряд имеют произведение строго меньше k. Числа от 1 и больше, k — любое целое, в том числе 0 и 1. Пример: [10, 5, 2, 6], k = 100 → 8. Время O(n), память O(1). Не меньше шести своих тестов: k = 0, k = 1, пустой список, один элемент, отрезок с произведением ровно k.Глава 10.5, §9: подсчёт отрезков; глава 10.6: границы

Тест к bugs_10.py засчитывается, если до исправления он падает, а после — проходит. Тест, который проходит и на ошибочной версии, ошибку не находит.

§8Порядок сдачи

Файлыportfolio/lesson_10/: solution.py, tests.py, bench_results.txt, complexity_note.md, initial_attempt.txt, bugs_10.py, tests_bugs_10.py, bugs_run.txt
Ветка и PRВетка hw-10, коммиты с содержательными сообщениями, Pull Request в собственную main. Объяснение решения проверяется по чек-листу из главы 10.6, §7
СрокДо начала занятия 11
ПроверяемЗелёный pytest по всем файлам; три теста к bugs_10.py, которые падают до исправления; шесть тестов к count_small_products; заметка без пустых пунктов
ИИКод и тесты пишете сами: на контроле занятия вы объясняете условие while и состояние окна своими словами. Оформление .md и редактуру формулировок можно поручить модели. Я сам так делаю всегда, поэтому и вам запрещать не буду.

§9Что дальше

Перед занятием 11 задачи модуля можно прорешать в формате собеседования: в главе 10.11 задачи на окно переменного размера идут по этапам секции с секундомером.

Занятие 11 — префиксные суммы и запросы на диапазоне. В главе 10.2 окно не подошло к отрезкам с отрицательными числами: по сумме нельзя было решить, какую границу сдвигать. Префиксная сумма решает такие задачи иначе: сумма любого отрезка [l, r) вычисляется одной разностью двух заранее посчитанных чисел, и знак элементов на это не влияет.

Модуль 10 · Окно переменного размера · ОП.04 · 3 курс Автор: Макаров Максим Николаевич