Разбор задачи: Плавание в поднимающейся воде

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

 import heapq

def swimInWater(grid):
    """
    Находит минимальное время, необходимое для достижения клетки (n-1, n-1) из клетки (0, 0).
    :param grid: List[List[int]] - матрица целочисленных значений
    :return: int - минимальное время t
    """
    n = len(grid)
    visited = [[False] * n for _ in range(n)]
    min_heap = [(grid[0][0], 0, 0)]  # (время, строка, столбец)
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    visited[0][0] = True
    result = 0

    while min_heap:
        t, x, y = heapq.heappop(min_heap)
        result = max(result, t)
        if x == n - 1 and y == n - 1:
            return result
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < n and 0 <= ny < n and not visited[nx][ny]:
                visited[nx][ny] = True
                heapq.heappush(min_heap, (grid[nx][ny], nx, ny))

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


Часть 1: Инициализация переменных

n = len(grid)
visited = [[False] * n for _ in range(n)]
min_heap = [(grid[0][0], 0, 0)]  # (время, строка, столбец)
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
visited[0][0] = True
result = 0
  1. n = len(grid): Здесь вычисляется размер матрицы. Поскольку матрица квадратная, количество строк равно количеству столбцов.
  2. visited: Создаётся матрица, отслеживающая, какие клетки уже посещены, чтобы избежать повторного их посещения.
  3. min_heap: Используется минимальная куча для отслеживания времени, необходимого для достижения каждой клетки. Она инициализируется начальной клеткой (grid[0][0], 0, 0), где:
    • grid[0][0] — время, необходимое для входа в клетку,
    • 0, 0 — координаты клетки.
  4. directions: Четыре возможных направления движения: вправо, вниз, влево, вверх.
  5. result = 0: Переменная для хранения максимального времени, необходимого для достижения текущей клетки.

Часть 2: Основной цикл

while min_heap:
    t, x, y = heapq.heappop(min_heap)
    result = max(result, t)
    if x == n - 1 and y == n - 1:
        return result
  1. while min_heap:: Цикл продолжается, пока есть клетки, которые нужно обработать.
  2. heapq.heappop(min_heap): Извлекается клетка с минимальным временем t.
  3. result = max(result, t): Обновляется максимальное время, необходимое для достижения текущей клетки. Это важно, поскольку вода должна "подняться" до уровня самой высокой клетки на пути.
  4. if x == n - 1 and y == n - 1:: Проверяется, достигли ли мы нижнего правого угла. Если да, возвращается значение result.

Часть 3: Обход соседей

for dx, dy in directions:
    nx, ny = x + dx, y + dy
    if 0 <= nx < n and 0 <= ny < n and not visited[nx][ny]:
        visited[nx][ny] = True
        heapq.heappush(min_heap, (grid[nx][ny], nx, ny))
  1. for dx, dy in directions:: Проходим по всем четырём возможным направлениям.
  2. nx, ny = x + dx, y + dy: Вычисляются координаты соседней клетки.
  3. if 0 <= nx < n and 0 <= ny < n and not visited[nx][ny]:: Убедимся, что соседняя клетка находится внутри границ матрицы и ещё не была посещена.
  4. visited[nx][ny] = True: Помечаем клетку как посещённую.
  5. heapq.heappush(min_heap, (grid[nx][ny], nx, ny)): Добавляем клетку в кучу, чтобы позже обработать её. Здесь:
    • grid[nx][ny] — высота текущей клетки, что равносильно времени, необходимому для её "доступности".

 



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