Представьте, что вы смотрите на текст через узкую прорезь-«окошко», которое можно растягивать и сдвигать. Вы тянете правый край окна вправо, добавляя буквы, пока в окне все буквы разные. Как только появился повтор — подтягиваете левый край, выбрасывая буквы слева, пока повтор не исчезнет. Всё время следите за самым широким окном, что удалось получить.
Условие
Дана строкаТекстовое значение в кавычках: "привет". Неизменяема. По-английски string (str).s. Найдите длину самой длинной подстроки без повторяющихся символов.
Держим «окно» — отрезок [left, right] без повторов. Двигаем right вправо, добавляя символы в множествоКоллекция уникальных элементов без порядка: {1, 2, 3}. По-английски set.. Если символ уже в окне — сдвигаем left вправо, убирая символы, пока повтор не исчезнет. На каждом шаге обновляем максимум длины окна.
▶ sliding-window.py
Разбор по строкам
seen = set() — буквы, которые сейчас в окне (для мгновенной проверки повтора).
left = 0 — левый край окна; right из циклаКонструкция, повторяющая блок кода: for перебирает элементы, while — пока условие истинно. — правый край.
while s[right] in seen — пока добавляемая буква уже в окне, сужаем слева: удаляем s[left] и двигаем left.
seen.add(s[right]) — теперь букву можно добавить: окно снова без повторов.
right - left + 1 — текущая ширина окна; обновляем рекорд best.
💡Совет
Скользящее окно превращает перебор всех подстрок O(n²) в один проход O(n). Признак, что приём подходит: ищется «самый длинный/короткий непрерывный участок при условии…». Очень частый паттерн на собеседованиях.
💡Совет
🔮 Предскажите вывод
Какова длина самой длинной подстроки без повторов в "abba"? Будьте внимательны: когда правый край дойдёт до второй a, левый край придётся подтянуть достаточно далеко.
▶ predict-window.py
Ответ — 2. Окно проходит «ab» (длина 2), затем на второй b сужается, на второй a левый край подтягивается за прошлую a. Максимум так и остаётся 2 (подстроки «ab» и «ab» в конце). Этот пример показывает, почему важно сужать окно в цикле while, а не один раз.
⚠️ Частые ошибки новичков
Частая ошибка — сужать окно через if вместо while. Одного удаления может не хватить, чтобы убрать повтор, и в множестве «застрянут» лишние символы. Запустите сломанный код: на "abba" он даёт неверный результат.
▶ broken-window.py
Заданиесложнаярешение.py
Реализуйте length_of_longest(s) — длину самой длинной подстроки без повторов, приёмом «скользящее окно» за O(n).
Заданиесложнаярешение.py
Доп. задача. Реализуйте longest_substr(s), который возвращает саму самую длинную подстроку без повторов (а не её длину). Если таких несколько — верните первую по порядку.
❓Проверь себя
Почему окно сужают циклом while, а не одним if?
Какова сложность решения скользящим окном?
Какой признак подсказывает, что задача решается скользящим окном?
ℹ️Важно
✅ Что вы узнали
Скользящее окно превращает перебор всех подстрок O(n²) в один проход O(n).
Множество seen даёт мгновенную проверку повтора в окне.
Сужать окно нужно циклом while, пока повтор не исчезнет, а не одним if.
Приём подходит для «самого длинного/короткого непрерывного участка при условии».
Комментарии
Загрузка…
Загрузка комментариев…