Бесплатная бета: 30 дней полного доступа, без карты.Зарегистрироваться бесплатно

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

Полевой справочник

Монотонная дек-очередь (максимум/минимум окна)

O(n)

Храни индексы в двусторонней очереди, значения в которой убывают (или возрастают); удаляй с начала индексы, выпавшие из окна, и удаляй с конца индексы, проигравшие новому значению, тогда начало очереди всегда даёт максимум (или минимум) текущего окна.

Сигналы

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

Шаблон

function maxSlidingWindow(nums, k) {
    const deque = []; // stores indices, values decreasing
    const result = [];
    for (let i = 0; i < nums.length; i++) {
        while (deque.length && deque[0] <= i - k) deque.shift();
        while (deque.length && nums[deque[deque.length - 1]] < nums[i]) deque.pop();
        deque.push(i);
        if (i >= k - 1) result.push(nums[deque[0]]);
    }
    return result;
}

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

  • Скользящее окно (фиксированное): Обычное фиксированное окно пересчитывает сумму за O(1) на шаг, но найти максимум/минимум окна так стоит O(k) на шаг (O(nk) итого), если пересканировать. Монотонная дек-очередь даёт максимум/минимум каждого окна за суммарный O(n), никогда не пересматривая проигравшее значение.
  • Монотонный стек: Монотонный стек снимает элементы только с одного конца (сверху). Здесь нужно убирать устаревшие индексы спереди по мере сдвига окна И снимать проигравшие значения сзади, а это требует обоих концов, то есть дек, а не односторонний стек.

n до 1e5 элементов, размер окна k -> O(n): каждый индекс входит и выходит из дек-очереди не более одного раза, суммарная работа линейна независимо от k.

Изучить этот паттерн