Все темы
56

Наибольшее значение за последние k отсчётов

Tier 1Закрыто

Где применяется

1. Задача

Панель мониторинга показывает пиковую задержку за последние 3 отсчёта (замера) и обновляется с каждым новым отсчётом. Окно скользит: свежий отсчёт входит справа, самый старый уходит слева, а ты сообщаешь максимум того, что внутри. Это надо делать для каждой позиции длинного потока.

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

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

Этот шаг из платной части

Бесплатные шаги в начале курса (их 33) открыты всем: урок, задача и тесты. Этот шаг открывается с полным доступом. Начни с бесплатного аккаунта и бесплатных шагов.

Завести бесплатный аккаунтПосмотреть, что входит
Максимум в каждом окне из 3 чисел
maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3)
nums
1
3
-1
-3
5
3
6
7
deque (индекс:значение, начало слева, значения убывают к концу)
пусто
result
пусто

Ищем максимум в каждом окне из 3 чисел. В деке лежат индексы, чьи значения ещё могут стать максимумом.

Гонка скорости
Максимум каждых 10 подряд идущих значений в одних и тех же 40 числах

Столбики: 40 значений. Окно длиной 10, это четверть массива, и таблица ниже сохраняет эту долю.

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

Повторный просмотр каждого окна O(n·k)
операций: 0
Монотонный дек O(n)
операций: 0

 

А если чисел больше

Операции для n чисел и примерное время при 100 миллионах простых операций в секунду. Это оценка по тому же счёту, а не замер.

n = 1 000
Повторный просмотр каждого окна187 тыс. · 1,9 мс
Монотонный дек1,7 тыс. · меньше 1 мс
n = 100 000
Повторный просмотр каждого окна1,9 млрд · 19 с
Монотонный дек170 тыс. · 1,7 мс
n = 10 000 000
Повторный просмотр каждого окна18,7 трлн · 2,2 дн.
Монотонный дек17 млн · 170 мс

Как узнать

Монотонная дек-очередь (максимум/минимум окна) (Monotonic deque (sliding window max/min))

Эти слова в условии значат этот паттерн

  • максимум или минимум каждого окна размера k
  • максимум/минимум скользящего окна
  • кратчайший подмассив с суммой не менее K
  • нужно снимать/класть с обоих концов очереди
  • дек, двусторонняя очередь

Похоже, но не то

n до 1e6 даёт O(n), ведь каждый индекс входит и выходит один раз. Память O(k) по размеру окна.

На LeetCode

Задачи, где на каждом шаге нужен максимум или минимум скользящего окна. Дек из позиций с убывающими значениями держит ответ в начале и стоит O(n) на весь проход.

Мы используем необходимые куки для работы сайта (вход и язык). Если ты согласишься, мы также загрузим Google Analytics, чтобы видеть, какие страницы читают, и Google reCAPTCHA для защиты форм обратной связи и сообщений об ошибке от спама. Политика конфиденциальности