Разбор задачи: Гниющие апельсины

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

 def orangesRotting(grid) -> int:
        bfs, t, m, n = [(i, j) for i, row in enumerate(grid) for j, val in enumerate(row) if val == 2], 0, len(grid), len(grid[0])
        while bfs:
            new = []
            for i, j in bfs:
                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):
                    if 0 <= x < m and 0 <= y < n and grid[x][y] == 1:
                        grid[x][y] = 2
                        new.append((x, y))
            bfs = new
            t += bool(bfs)
        return t if all(val != 1 for row in grid for val in row) else -1

1. Инициализация начального состояния

bfs = [(i, j) for i, row in enumerate(grid) for j, val in enumerate(row) if val == 2]
t, m, n = 0, len(grid), len(grid[0])
  • Что здесь происходит?
    • Мы создаем список bfs, который содержит координаты всех гнилых апельсинов (i, j). Это исходная очередь для обработки.
    • t — это переменная, которая отслеживает количество минут, прошедших с начала процесса.
    • m и n — размеры матрицы grid (количество строк и столбцов).
  • Почему это важно?
    • Наличие начальной очереди bfs позволяет сразу работать только с гнилыми апельсинами, пропуская пустые ячейки и свежие апельсины.
    • Размеры матрицы нужны для проверки, что мы не выходим за её границы.

2. Основной цикл распространения гнили

while bfs:
    new = []
    for i, j in bfs:
        for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):
            if 0 <= x < m and 0 <= y < n and grid[x][y] == 1:
                grid[x][y] = 2
                new.append((x, y))
    bfs = new
    t += bool(bfs)
  • Что здесь происходит?
    • Пока есть гнилые апельсины, мы запускаем цикл while.
    • Внутри цикла:
      1. Создаем временный список new, который будет хранить координаты свежих апельсинов, ставших гнилыми за текущую минуту.
      2. Для каждого апельсина (i, j) в текущей очереди bfs проверяем его соседей в четырёх направлениях: вверх, вниз, влево, вправо.
      3. Если соседняя ячейка содержит свежий апельсин (grid[x][y] == 1), то:
        • Мы делаем его гнилым: grid[x][y] = 2.
        • Добавляем его координаты в список new.
    • После обработки всех гнилых апельсинов обновляем очередь bfs новой партией гнилых апельсинов: bfs = new.
    • Увеличиваем время t, если есть новые гнилые апельсины (bool(bfs)).
  • Почему это работает?
    • Цикл while моделирует распространение гнили минуту за минутой.
    • Список new помогает учитывать только свежие апельсины, ставшие гнилыми на текущем шаге.
    • Условие 0 <= x < m and 0 <= y < n гарантирует, что мы не выйдем за границы матрицы.

3. Проверка оставшихся свежих апельсинов

return t if all(val != 1 for row in grid for val in row) else -1
  • Что здесь происходит?
    • Мы проверяем, остались ли в матрице свежие апельсины:
      • all(val != 1 for row in grid for val in row) возвращает True, если в матрице нет ячеек со значением 1.
    • Если свежих апельсинов больше нет, возвращаем количество минут t.
    • Если хотя бы один свежий апельсин остался, возвращаем -1.
  • Почему это нужно?
    • Если свежие апельсины остались, значит, их невозможно заразить, и задача должна вернуть -1.

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

Рассмотрим пример:

Ввод:

grid = [[2, 1, 1],
        [1, 1, 0],
        [0, 1, 1]]

Шаги выполнения:

  1. Инициализация:
    • bfs = [(0, 0)] (координаты гнилых апельсинов).
    • t = 0.
  2. Первая итерация while:
    • bfs = [(0, 0)], то есть один гнилой апельсин.
    • Проверяем его соседей:
      • (0, 1) становится гнилым.
      • (1, 0) становится гнилым.
    • new = [(0, 1), (1, 0)].
    • Обновляем bfs и увеличиваем t: t = 1.
  3. Вторая итерация while:
    • bfs = [(0, 1), (1, 0)].
    • Проверяем соседей:
      • (0, 2) становится гнилым.
      • (1, 1) становится гнилым.
    • new = [(0, 2), (1, 1)].
    • Обновляем bfs и увеличиваем t: t = 2.
  4. Третья итерация while:
    • bfs = [(0, 2), (1, 1)].
    • Проверяем соседей:
      • (2, 1) становится гнилым.
    • new = [(2, 1)].
    • Обновляем bfs и увеличиваем t: t = 3.
  5. Четвертая итерация while:
    • bfs = [(2, 1)].
    • Проверяем соседей:
      • (2, 2) становится гнилым.
    • new = [(2, 2)].
    • Обновляем bfs и увеличиваем t: t = 4.
  6. Пятая итерация while:
    • bfs = [(2, 2)].
    • Нет новых гнилых апельсинов.
    • new = [].
  7. Завершение работы:
    • bfs = [] (очередь пуста).
    • Проверяем, остались ли свежие апельсины: их нет.
    • Возвращаем t = 4.

Вывод:

4

 



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