Разбор задачи: Максимальное количество последовательных единиц

Предложенный нами код:

 def maxConsecutiveOnes(nums, k):
    """
    :param nums: List[int] - бинарный массив, содержащий только 0 и 1
    :param k: int - максимальное количество нулей, которые можно перевернуть
    :return: int - максимальное количество последовательных единиц
    """
    left = 0
    max_length = 0
    zeros_flipped = 0

    for right in range(len(nums)):
        # Если текущий элемент 0, увеличиваем счетчик переворотов
        if nums[right] == 0:
            zeros_flipped += 1
        
        # Если переворотов больше, чем k, сдвигаем левую границу
        while zeros_flipped > k:
            if nums[left] == 0:
                zeros_flipped -= 1
            left += 1
        
        # Обновляем максимальную длину
        max_length = max(max_length, right - left + 1)
    
    return max_length

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


1. Описание параметров

left = 0
max_length = 0
zeros_flipped = 0
  • left — это индекс левой границы текущего окна.
  • max_length — переменная для хранения максимальной длины последовательности единиц.
  • zeros_flipped — количество нулей, перевернутых в единицы в текущем окне.

2. Основной цикл

for right in range(len(nums)):
    if nums[right] == 0:
        zeros_flipped += 1

Цикл проходит по всем элементам массива nums:

  • Если текущий элемент равен 0, увеличиваем счётчик zeros_flipped, так как "переворачиваем" этот ноль.

3. Проверка на превышение лимита переворотов

while zeros_flipped > k:
    if nums[left] == 0:
        zeros_flipped -= 1
    left += 1

Если количество перевернутых нулей превышает заданный лимит k, сдвигаем левую границу окна вправо (left += 1) до тех пор, пока условие не станет истинным. Если элемент на позиции left равен 0, уменьшаем счётчик zeros_flipped, так как этот ноль больше не входит в окно.


4. Обновление максимальной длины

max_length = max(max_length, right - left + 1)

На каждом шаге вычисляем длину текущего окна (right - left + 1) и обновляем max_length, если текущее окно больше предыдущего максимального.


5. Возврат результата

return max_length

После завершения прохода по массиву возвращаем максимальную длину последовательности единиц, которую удалось получить.


Пример работы алгоритма

Входные данные:

nums = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0]
k = 2

  1. Итерация 1–3 (right = 0, 1, 2):
    • Массив окна: [1, 1, 1]
    • Нули: 0 (в пределах лимита k = 2)
    • Длина окна: 3
    • max_length = 3

  1. Итерация 4 (right = 3):
    • Массив окна: [1, 1, 1, 0]
    • Нули: 1 (в пределах лимита k = 2)
    • Длина окна: 4
    • max_length = 4

  1. Итерация 6 (right = 5):
    • Массив окна: [1, 1, 1, 0, 0, 0]
    • Нули: 3 (превышает лимит k = 2)
    • Сдвигаем left до тех пор, пока не уберём лишний ноль.
    • Новый массив окна: [1, 0, 0, 1, 1, 1, 1]
    • Длина окна: 6
    • max_length = 6

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии