1. Вопрос 24. Два указателя и скользящее окно. Шаблон 1 — "НЕ БОЛЕЕ K раз", ищем МАКСИМУМ


Оба метода работают с подстроками и используют два указателя left и right:

Строка:  A B X A X X A B A
         ↑       ↑
        left   right
         └───────┘
         окно (подстрока)
Главное правило: оба указателя двигаются только ВПРАВО → сложность O(n).

Шаблон 1 — "НЕ БОЛЕЕ K раз", ищем МАКСИМУМ

Задача-пример

Найти максимальную подстроку, где буква X встречается не более 2 раз.

Строка: A B X A X X A B

Принцип

1. Двигаем right вправо, добавляя символы в окно
2. Если условие нарушено (X больше 2) — двигаем left вправо
3. После исправления окно всегда валидно → обновляем максимум

Пошаговый разбор

Строка: A B X A X X A B
        0 1 2 3 4 5 6 7

Начало: left=0, count_x=0, max_len=0

Шаг 1: right=0, символ 'A'


        A B X A X X A B
        ↑
        L,R
        
count_x = 0 (≤2)
max_len = max(0, 0-0+1) = 1

Шаг 2: right=1, символ 'B'


        A B X A X X A B
        ↑ ↑
        L R
        
count_x = 0 (≤2)
max_len = max(1, 1-0+1) = 2

Шаг 3: right=2, символ 'X'


        A B X A X X A B
        ↑   ↑
        L   R
        
count_x = 1 (≤2)
max_len = max(2, 2-0+1) = 3

Шаг 4: right=3, символ 'A'


        A B X A X X A B
        ↑     ↑
        L     R
        
count_x = 1 (≤2)
max_len = max(3, 3-0+1) = 4

Шаг 5: right=4, символ 'X'


        A B X A X X A B
        ↑       ↑
        L       R
        
count_x = 2 (≤2)
max_len = max(4, 4-0+1) = 5

Шаг 6: right=5, символ 'X'


        A B X A X X A B
        ↑         ↑
        L         R
        
count_x = 3 (>2 ✗) — условие НАРУШЕНО!

Сужаем окно, двигаем left:
  left=0: 'A' — не X, просто сдвигаем
  left=1: 'B' — не X, просто сдвигаем  
  left=2: 'X' — это X! count_x = 2
  left=3 (остановились, т.к. count_x ≤ 2)

        A B X A X X A B
              ↑     ↑
              L     R

count_x = 2 (≤2 ✓)
max_len = max(5, 5-3+1) = 5

Шаг 7: right=6, символ 'A'


        A B X A X X A B
              ↑       ↑
              L       R
        
count_x = 2 (≤2 ✓)
max_len = max(5, 6-3+1) = 5

Шаг 8: right=7, символ 'B'


        A B X A X X A B
              ↑         ↑
              L         R
        
count_x = 2 (≤2 ✓)
max_len = max(5, 7-3+1) = 5

Ответ: 5

Максимальная подстрока: A X X A B (позиции 3-7) или A B X A X (позиции 0-4)


Код


def max_at_most_k(s, k):
    left = 0
    count_x = 0
    max_len = 0
    
    for right in range(len(s)):
        if s[right] == 'X':
            count_x += 1
        
        while count_x > k:          # пока нарушено
            if s[left] == 'X':
                count_x -= 1
            left += 1
        
        max_len = max(max_len, right - left + 1)  # ПОСЛЕ while
    
    return max_len

 

Ключевое правило Шаблона 1
┌────────────────────────────────────────────┐
│  while count > k    ← сужаем ПОКА нарушено │
│  обновляем ПОСЛЕ while ← окно уже валидно  │
└────────────────────────────────────────────┘

time 1000 ms
memory 256 Mb

Комментарий учителя