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

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

Глава 10.1

10.1

Окно переменного размера
на собеседованиях и в работе

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

Категория
Обзор темы
Уровень
Начальный
Опирается на
Модуль 9: окно [l, r) и состояние окна; модуль 8: указатели в одну сторону
Зачем это знать
Понимать, какие задачи модуля встретятся на интервью

§1Задачи с условием на подотрезок

В модуле 9 длина подотрезка была записана в условии числом: «отрезок длины k», «за любые 3 часа подряд». В задачах этого модуля длина в условии не названа. Вместо неё задано требование к подотрезку: сумма не меньше порога, все символы разные, нулей не больше двух. Нужно найти самый короткий или самый длинный подотрезок, который это требование выполняет. Обе типичные задачи алгоритмической секции из статьи журнала Яндекс Образования устроены так же.

«Типичный пример первой задачи: в массиве из чисел нужно найти наибольший неубывающий подотрезок, то есть такой подотрезок из чисел, где каждое следующее число больше или равно предыдущему».

«Типичный пример второй задачи: дан массив чисел, требуется найти число подмассивов, в которых значения всех чисел различны».

Там же

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

Там же сказано, что оценивают на секции. Каждому пункту этой оценки в модуле соответствует своя глава.

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

Там же
Что оценивают на секцииГде это в модуле
Решение одним проходом вместо перебора всех подотрезковГлавы 10.3–10.5: расширение и сжатие окна, две задачи КТП
Внятное изложение алгоритмаГлава 10.9: как объяснить условие цикла while и состояние окна
Оценка сложностиГлавы 10.3 и 10.7: почему проход стоит O(n) и замер против перебора
Ошибки в коде и их исправлениеГлавы 10.6 и 10.9: пустая строка, повторы, ответа нет

§2Окно переменного размера в программах подготовки

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

ПрограммаРаздел Sliding WindowЗадачи на окно переменного размера
LeetCode 75643, 1456, 1004, 14931004 и 1493 — две из четырёх
LeetCode · Top Interview 150209, 3, 30, 76209, 3 и 76 — три из четырёх; в задаче 30 длина окна задана условием

Задачи 643 и 1456 из первой программы разобраны в модуле 9. Задачи 209 и 3 из второй программы — практика этого занятия по КТП: «Решить задачи на минимальный отрезок с суммой не меньше S и подстроку без повторов». Задача 209 разобрана в главе 10.4, задача 3 — в главе 10.5.

§3Задачи с собеседований

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

Номер и названиеСложностьЧто нужно найтиТребование к подотрезку
209 · Minimum Size Subarray SumMediumСамый короткий отрезокСумма не меньше заданного числа
3 · Longest Substring Without Repeating CharactersMediumСамую длинную подстрокуВсе символы разные
1004 · Max Consecutive Ones IIIMediumСамый длинный отрезокНулей не больше k
1493 · Longest Subarray of 1's After Deleting One ElementMediumСамый длинный отрезокНулей не больше одного
904 · Fruit Into BasketsMediumСамый длинный отрезокРазных значений не больше двух
2958 · Length of Longest Subarray With at Most K FrequencyMediumСамый длинный отрезокКаждое значение встречается не больше k раз
424 · Longest Repeating Character ReplacementMediumСамую длинную подстрокуЗаменой не больше k символов её можно сделать строкой из одной буквы
713 · Subarray Product Less Than KMediumЧисло отрезковПроизведение меньше k
76 · Minimum Window SubstringHardСамую короткую подстрокуВ ней есть все символы образца

В задачах 209, 713, 1004 и 1493 для проверки требования достаточно одного числа: суммы, произведения или счётчика нулей. В задачах 3, 904, 2958, 424 и 76 нужно знать, сколько раз каждое значение встречается в окне. Для этого в окне ведут словарь «значение → сколько раз встретилось», его называют частотной картой. Задачи модуля идут в этом порядке: сначала окно с суммой, затем окно с частотной картой. Задача 76 уровня Hard в модуль не входит, в таблице она показывает, до какой сложности доходит тот же приём.

§4Где приём работает в программах

Окно, у которого границы двигаются по отдельности, встречается там, где данные идут потоком, а участок, с которым работает программа, ограничен условием.

Где встречается
  • Передача данных по сети. В протоколе TCP отправитель хранит участок данных, которые уже отправлены, но ещё не подтверждены получателем. В стандарте RFC 9293 его границы названы SND.UNA и SND.NXT. Правая граница сдвигается, когда отправляются новые данные, левая — когда приходит подтверждение. Размер участка ограничен числом SND.WND, которое сообщает получатель, и во время работы меняется.
  • Анализ журнала событий. «За какой самый короткий промежуток набралось сто ошибок», «какая самая длинная серия запросов, в которой не больше двух отказов» — вопросы к журналу сервера. Длина промежутка заранее неизвестна, она определяется условием на содержимое.
  • Ограничение частоты запросов. В главе 9.5 левая граница окна уже сдвигалась циклом while, пока в окне оставались устаревшие события. Длина окна по времени там была постоянной, а число событий в окне менялось. В этом модуле тот же цикл работает с любым условием.

Дальше в главе используется один пример. В списке записано число заказов интернет-магазина по часам. Нужно найти самый короткий промежуток из часов подряд, за который набралось не меньше 30 заказов. Первый способ — перебрать все подотрезки и проверить сумму каждого.

Терминалpython -i · Python 3.12
>>> orders = [5, 8, 3, 12, 20, 6, 22, 9]
>>> segments = [(l, r) for l in range(8) for r in range(l + 1, 9)]
>>> len(segments)
36
>>> good = [(l, r) for l, r in segments if sum(orders[l:r]) >= 30]
>>> len(good)
20
>>> min(good, key=lambda p: p[1] - p[0])
(3, 5)
>>> orders[3:5]
[12, 20]

В списке из восьми элементов 36 подотрезков, у 20 из них сумма не меньше 30. Самый короткий — orders[3:5], два часа с 12 и 20 заказами. Ответ верный. Чтобы его получить, перебор проверил все 36 подотрезков и сумму каждого посчитал заново. У списка из n элементов подотрезков n·(n + 1)/2, поэтому перебор стоит не меньше O(n²). Окно переменного размера находит тот же ответ за один проход.

§5Расширение и сжатие окна

Перед определениями — сравнение из жизни, на котором видно, как двигаются границы окна.

Для наглядности
Гусеница на ветке

Гусеница ползёт в два движения. Сначала она вытягивает вперёд голову, и тело становится длиннее. Затем подтягивает хвост, и тело становится короче. Голова и хвост двигаются по очереди и только вперёд, назад гусеница не ползёт.

Что это в коде

Ветка — список, тело гусеницы — окно a[l:r]. Голова — правая граница: r += 1 добавляет в окно элемент. Хвост — левая граница: l += 1 убирает из окна элемент. Какая граница сдвигается на очередном шаге, определяет требование задачи.

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

Теперь то же самое точными словами. Окно записывается так же, как в модуле 9, полуинтервалом [l, r). В него входят элементы от a[l] до a[r − 1], длина равна r − l. Новых понятий три.

Условие допустимостиwindow condition

Требование задачи к подотрезку, записанное как проверка, которая отвечает «да» или «нет»: total >= s, «в окне нет повторов», «нулей в окне не больше k». Окно, для которого проверка отвечает «да», называют допустимым.

Проверка должна работать за O(1). Поэтому элементы окна она не перебирает. Она читает состояние окна из модуля 9: сумму, счётчик или частотную карту.

Расширение и сжатиеexpand · shrink

Расширение — сдвиг правой границы: элемент a[r] добавляется в состояние окна, затем r += 1. Сжатие — сдвиг левой границы: элемент a[l] убирается из состояния окна, затем l += 1. Расширение увеличивает длину окна на единицу, сжатие уменьшает на единицу.

Скользящее окно переменного размераvariable-size sliding window

Техника прохода, в которой правая граница окна идёт по списку слева направо, а левая сдвигается вслед за ней, пока этого требует условие допустимости. Обе границы двигаются только вправо. Каждая проходит список не больше одного раза, поэтому сдвигов не больше 2·n и весь проход стоит O(n).

В блоке ниже решается задача о заказах из §4. Условие допустимости — «сумма окна не меньше S». Кнопка «шаг» сдвигает одну границу: правую, пока сумма меньше порога, и левую, когда сумма порога достигла. Перед каждым сжатием длина окна сравнивается с самым коротким из найденных. Под лентой показано, сколько раз сдвинута каждая граница.

При пороге 30 окно сначала расширяется пять раз подряд, до суммы 48. После этого оно четыре раза подряд сжимается. Перед каждым сжатием окно подходит, и его длина записывается: 5, 4, 3, 2. Окно a[3:5] длины 2 — то же, что нашёл перебор. Правая граница за весь проход сдвинута 8 раз, левая — 7 раз: 15 сдвигов вместо 36 проверок с суммой каждого подотрезка. Порог можно менять кнопками. При пороге 90 подходящего окна нет, потому что сумма всех элементов равна 85.

С ростом списка разница увеличивается: число подотрезков растёт как n², число сдвигов границ — как n.

nПодотрезков: n·(n + 1)/2Сдвигов границ: не больше 2·n
83616
1 000500 5002 000
100 0005 000 050 000200 000

Способ работает при одном ограничении на данные: числа в списке неотрицательные. Тогда расширение не уменьшает сумму, а сжатие не увеличивает, и по сумме понятно, какую границу сдвигать. С отрицательными числами это правило нарушается. Вопрос о знаке чисел задают интервьюеру до решения, он разобран в главе 10.2, а причина ограничения — в главе 10.3.

§6Сравнение с окном фиксированной длины

Окно переменного размера собрано из уже известных частей. Запись окна полуинтервалом и состояние окна взяты из модуля 9. Два указателя, которые идут в одну сторону с разной скоростью, — из модуля 8. Новое здесь одно: сдвигом левой границы управляет условие допустимости.

Указатели в одну сторону, модуль 8Окно фиксированной длины, модуль 9Окно переменного размера, модуль 10
Указателиr читает, w пишетl — начало окна, r = l + k — конецl — начало окна, r — конец
Расстояние между нимиМеняется, смысла в задаче не имеетВсегда kМеняется, это длина окна и часть ответа
Когда сдвигается левыйПосле записи элементаНа каждом шаге, вместе с правымКогда этого требует условие допустимости
Что хранится между шагамиПозиция записиСостояние окна: сумма, счётчикСостояние окна и лучший найденный ответ
Сколько сдвиговНе больше 2·n2·(n − k) после первого окнаНе больше 2·n

Из таблицы следует, что код окна переменного размера отличается от кода модуля 9 одним местом. В главах 9.3 и 9.4 левая граница сдвигалась на каждом шаге без проверки. Здесь на её месте стоит цикл while с условием допустимости. Поэтому в контроле занятия по КТП записано: «Кандидат объясняет условие while и состояние окна».

§7Две постановки задачи

Задачи из таблицы §3 делятся на две группы по тому, что нужно найти: самый короткий допустимый отрезок или самый длинный. От этого зависит, когда окно сжимается и в какой момент записывается ответ.

Самый короткий отрезокСамый длинный отрезок
Пример условияСумма не меньше SВ подстроке нет повторов
Что делает расширениеПриближает окно к допустимому: сумма растётМожет сделать окно недопустимым: пришёл повтор
Когда окно сжимаетсяПока окно допустимоПока окно недопустимо
Когда записывается ответПеред каждым сжатиемПосле того как сжатие закончилось
Состояние окнаСуммаЧастотная карта или множество
Задача модуляLeetCode 209, глава 10.4LeetCode 3, глава 10.5

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

§8Карта модуля

Модуль построен так же, как модули 8 и 9: от того, как задачу формулируют и уточняют, к решению, крайним случаям и замеру. Главы 10.1 и 10.2 — про условие, 10.3–10.5 — про сами алгоритмы, 10.6 и 10.7 — про проверку. Глава 10.8 проводит новую задачу через все этапы собеседования, 10.9 собирает ошибки модуля и объяснение решения, 10.10 — практика и домашнее задание, 10.11 — тренажёр в формате собеседования.

  1. 10.2 Формулировки и вопросы до решения. Как звучат задачи на окно переменного размера и что уточнить до кода: знак чисел, пустой вход, что вернуть, если ответа нет.
  2. 10.3 Условие допустимости, расширение и сжатие. Общая схема прохода, цикл while, почему левая граница не возвращается назад и откуда O(n).
  3. 10.4 Минимальный отрезок с суммой не меньше S. Задача КТП, LeetCode 209: перебор, окно, пошаговый прогон.
  4. 10.5 Подстрока без повторов и частотная карта. Задача КТП, LeetCode 3: словарь в роли состояния окна.
  5. 10.6 Границы. Пустая строка, повторы, один элемент, ответа нет — тесты из контроля КТП.
  6. 10.7 Замер. Окно против перебора всех подотрезков на списках разной длины.
  7. 10.8 Задача целиком. Новая задача от условия до проверки в порядке interview canvas, с ориентиром по минутам.
  8. 10.9 Ошибки и объяснение решения. Сводка ошибок модуля по симптомам и что говорить интервьюеру об условии while.
  9. 10.10 Практика и ДЗ. Стартовый набор, тесты, шпаргалка, домашнее задание.
  10. 10.11 Мок-интервью. Задачи на окно переменного размера по этапам секции с секундомером.

§9Проверьте себя

Вопрос 1В списке 1 000 элементов. Сколько раз за весь проход может сдвинуться левая граница окна переменного размера?

  • Это число подотрезков, столько проверок делает перебор. Окно подотрезки не перебирает: каждая граница идёт по списку один раз.

  • Левая граница назад не возвращается. Сдвиги, сделанные на одном шаге правой границы, на следующих шагах не повторяются.

  • Верно. Левая граница двигается только вправо и не обгоняет правую, поэтому проходит список не больше одного раза.

Вопрос 2Задача: «найти самый длинный отрезок, в котором нулей не больше двух». Что здесь условие допустимости и что состояние окна?

  • Верно. Счётчик увеличивается, когда в окно входит ноль, и уменьшается, когда ноль выходит. Проверка zeros <= 2 работает за O(1).

  • Ограничение стоит на число нулей в окне. Длина окна в условии не задана, её и нужно найти.

  • Положение нулей в условии не ограничено, ограничено их количество. Для него нужен счётчик нулей в окне.

Вопрос 3Ищут самый короткий отрезок с суммой не меньше 30. Сумма текущего окна равна 48. Что делает алгоритм на этом шаге?

  • Сумма уже не меньше порога. Расширение сделает окно длиннее, а ищут самое короткое.

  • Верно. Окно допустимо, поэтому его длина — кандидат в ответ. После записи левая граница сдвигается: возможно, более короткое окно тоже допустимо.

  • Найдено допустимое окно, но не обязательно самое короткое. В примере из §5 после суммы 48 длина уменьшалась ещё три раза.

Источники главы
  1. Журнал Яндекс Образования. Алгоритмические собеседования в Яндексе: как подготовиться и чего ожидать — education.yandex.ru/journal; цитаты сверены 13.10.2026
  2. LeetCode. LeetCode 75 — leetcode.com/studyplan/leetcode-75; состав раздела Sliding Window проверен по данным сайта 13.10.2026
  3. LeetCode. Top Interview 150 — leetcode.com/studyplan/top-interview-150; состав раздела, метки и сложность задач проверены 13.10.2026
  4. RFC 9293. Transmission Control Protocol (TCP), раздел 3.3.1 — rfc-editor.org/rfc/rfc9293
  5. КТП ОП.04, занятие 10
Модуль 10 · Окно переменного размера · ОП.04 · 3 курс Автор: Макаров Максим Николаевич