Помимо Техника с двумя указателями В моем предыдущем посте я продемонстрировал еще одну популярную алгоритмическую ментальную модель: скользящее окно Анкет
Если вы никогда не слышали о технике скользящего окна, я настоятельно рекомендую посмотреть Этот видеоурок Перед погружением в пример ниже. Даже если у вас нет 36 минут, обязательно посмотрите первые 8 минут, которые содержат несколько хорошо выполненных анимаций.
Что такое техника скользящего окна?
Как следует из названия, этот метод включает в себя взятие данных из данного массива или строки, расширения или сокращения этого подмножества для удовлетворения определенных условий, отсюда и скольжение эффект.
(⬆ изображение с помощью Простое инженерное видео )
Когда мы можем его использовать?
Вообще говоря, техника скользящего окна полезна, когда вам нужно отслеживать смежный Последовательность элементов, таких как суммирование значений в субраре.
Вот классический пример (любезно предоставлено Курс Udemy Colt Steele ):
Учитывая множество положительных целых чисел и положительное целое число, Напишите функцию, которая возвращает Минимальная длина смежного субрай, где сумма больше или равна целому числу, передаваемому. Если нет, верните 0.
И вот несколько тестовых случаев:
minSubArrayLen([2, 3, 1, 2, 4, 3], 7) // 2 -> [4, 3] is the smallest subarray minSubArrayLen([3, 1, 7, 8, 62, 18, 9], 52) // 1 -> [62] is the smallest subarray minSubArrayLen([1, 4, 16, 22, 5], 95) // 0
Чтобы реализовать технику скользящего окна для этой задачи, нам нужно сначала выяснить диапазон окна. В этом случае мы «открывают» окно слева.
Затем нам нужно сохранить сумму значений в прилагаемом Subarray/Window и сравнить ее с целевым целым числом.
Если сумма соответствует условию (больше или равна целому числу), мы записываем длину текущего диапазона окна и продолжаем сокращать окно, поскольку нам нужно найти Минимальный длина.
Если сумма не соответствует условию, то мы продолжаем расширять правую панель окна (потому что мы итерация слева).
Если сумма никогда не соответствует цели, мы выходим из петли и возвращаем 0 вместо этого.
Собрать это вместе:
function minSubArrayLen(arr, target) {
let minLength = Infinity
let sum = 0
let left = 0
let right = 0
while (left < arr.length) {
if (sum >= target) {
// store the current minimal length
minLength = Math.min(minLength, (right - left))
// shrink the window:
// (1) subtract the value at left idx
// (2) move the left panel one index further to the right
sum -= arr[left]
left++
} else if (sum < target && right < arr.length) {
// expand the window:
// (1) sum up the current value
// (2) move the right panel one index further to the right
sum += arr[right]
right++
} else {
break
}
}
return minLength === Infinity ? 0 : minLength
}
Используя технику скользящего окна, мы можем решить проблему выше со сложностью времени O (n), устраняя необходимость дублирования итераций. Снимаю шляпу перед человеком/командой, который придумал этот мощный инструмент!
Оригинал: “https://dev.to/liaowow/understanding-the-sliding-window-technique-in-algorithms-206o”