Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. BFS: Сетки
bfs_grid

BFS: Сетки

Number of Islands, Rotting Oranges, Walls and Gates.

BFS: Задачи на сетках

Многоисточниковый BFS для задач на сетках. Подсчёт островов, распространение, заполнение.

#1. Number of Islands (LeetCode 200) — BFS версия 🟦 Medium

Ссылка: https://leetcode.com/problems/number-of-islands/

Условие: Дана двумерная сетка grid, состоящая из символов '1' (земля) и '0' (вода). Верните количество островов.

Остров окружён водой и образован соединением соседних по горизонтали или вертикали земель.

Примеры:

Ввод: grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
Вывод: 1

Ввод: grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
Вывод: 3

Ограничения:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] — символ '0' или '1'

💡 Подсказка: Проходите по каждой клетке. При встрече '1' запускайте BFS, помечая всю компоненту связности (заменяя '1' на '0').

Решение:

from collections import deque def numIslands(grid): if not grid: return 0 rows, cols = len(grid), len(grid[0]) count = 0 def bfs(r, c): queue = deque([(r, c)]) grid[r][c] = '0' while queue: row, col = queue.popleft() for dr, dc in [(1,0), (-1,0), (0,1), (0,-1)]: nr, nc = row + dr, col + dc if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == '1': grid[nr][nc] = '0' queue.append((nr, nc)) for i in range(rows): for j in range(cols): if grid[i][j] == '1': bfs(i, j) count += 1 return count

Объяснение:

  • Проходим по каждой клетке
  • При встрече '1' запускаем BFS, помечая всю компоненту (заменяя на '0')
  • Увеличиваем счётчик островов

Сложность:

  • Время: O(m × n)
  • Память: O(min(m, n)) — максимальный размер очереди

#2. Rotting Oranges (LeetCode 994) 🟦 Medium

Ссылка: https://leetcode.com/problems/rotting-oranges/

Условие: Дана сетка m x n, где каждая клетка может иметь одно из трёх значений:

  • 0 — пустая клетка
  • 1 — свежий апельсин
  • 2 — гнилой апельсин

Каждую минуту любой свежий апельсин, соседствующий (4 направления) с гнилым, становится гнилым.

Верните минимальное количество минут, которое должно пройти, чтобы все апельсины стали гнилыми. Если это невозможно, верните -1.

Примеры:

Ввод: grid = [[2,1,1],[1,1,0],[0,1,1]]
Вывод: 4

Ввод: grid = [[2,1,1],[0,1,1],[1,0,1]]
Вывод: -1

Ввод: grid = [[0,2]]
Вывод: 0

Ограничения:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] — 0, 1 или 2

💡 Подсказка: Используйте многоисточниковый BFS. Добавьте все гнилые апельсины в очередь изначально. Считайте количество свежих апельсинов.

Решение:

from collections import deque def orangesRotting(grid): rows, cols = len(grid), len(grid[0]) queue = deque() fresh = 0 # Находим все гнилые апельсины и считаем свежие for i in range(rows): for j in range(cols): if grid[i][j] == 2: queue.append((i, j)) elif grid[i][j] == 1: fresh += 1 if fresh == 0: return 0 minutes = 0 directions = [(1,0), (-1,0), (0,1), (0,-1)] while queue and fresh > 0: for _ in range(len(queue)): r, c = queue.popleft() for dr, dc in directions: nr, nc = r + dr, c + dc if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1: grid[nr][nc] = 2 fresh -= 1 queue.append((nr, nc)) minutes += 1 return minutes if fresh == 0 else -1

Объяснение:

  • Многоисточниковый BFS: все гнилые апельсины в очереди изначально
  • Каждый уровень BFS = 1 минута
  • Если после BFS остались свежие (fresh > 0), возвращаем -1

Сложность:

  • Время: O(m × n)
  • Память: O(m × n)

#3. Walls and Gates (LeetCode 286) 🟦 Medium

Ссылка: https://leetcode.com/problems/walls-and-gates/

Условие: Дана сетка m x n с тремя типами клеток:

  • -1 — стена или препятствие
  • 0 — ворота
  • INF (2147483647) — пустая комната

Заполните каждую пустую комнату расстоянием до ближайших ворот. Если комната не может достичь ворот, оставьте INF.

Примеры:

Ввод: rooms = [
  [INF, -1,  0, INF],
  [INF, INF, INF, -1],
  [INF, -1, INF, -1],
  [  0, -1, INF, INF]
]
Вывод: [
  [  3, -1,   0,   1],
  [  2,  2,   1,  -1],
  [  1, -1,   2,  -1],
  [  0, -1,   3,   4]
]

Ограничения:

  • m == rooms.length
  • n == rooms[i].length
  • 1 <= m, n <= 250

💡 Подсказка: Используйте многоисточниковый BFS. Добавьте все ворота в очередь изначально.

Решение:

from collections import deque def wallsAndGates(rooms): if not rooms: return rows, cols = len(rooms), len(rooms[0]) queue = deque() # Находим все ворота for i in range(rows): for j in range(cols): if rooms[i][j] == 0: queue.append((i, j)) directions = [(1,0), (-1,0), (0,1), (0,-1)] while queue: r, c = queue.popleft() for dr, dc in directions: nr, nc = r + dr, c + dc if 0 <= nr < rows and 0 <= nc < cols and rooms[nr][nc] == float('inf'): rooms[nr][nc] = rooms[r][c] + 1 queue.append((nr, nc))

Объяснение:

  • Многоисточниковый BFS от всех ворот одновременно
  • Распространяем расстояние: rooms[nr][nc] = rooms[r][c] + 1
  • Посещаем только клетки с INF

Сложность:

  • Время: O(m × n)
  • Память: O(m × n)

#4. Max Area of Island (LeetCode 695) 🟦 Medium

Ссылка: https://leetcode.com/problems/max-area-of-island/

Условие: Дана двумерная сетка grid, состоящая из символов '1' (земля) и '0' (вода). Верните максимальную площадь острова.

Остров окружён водой и образован соединением соседних по горизонтали или вертикали земель.

Примеры:

Ввод: grid = [
  [0,0,1,0,0,0,0,1,0,0,0,0,0],
  [0,0,0,0,0,0,0,1,1,1,0,0,0],
  [0,1,1,0,1,0,0,0,0,0,0,0,0],
  [0,1,0,0,1,1,0,0,1,0,1,0,0],
  [0,1,0,0,1,1,0,0,1,1,1,0,0],
  [0,0,0,0,0,0,0,0,0,0,1,0,0],
  [0,0,0,0,0,0,0,1,1,1,0,0,0],
  [0,0,0,0,0,0,0,1,1,0,0,0,0]
]
Вывод: 6

Ограничения:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] — '0' или '1'

💡 Подсказка: BFS для каждой компоненты связности. Считайте количество клеток в компоненте.

Решение (BFS версия):

from collections import deque def maxAreaOfIsland(grid): if not grid: return 0 rows, cols = len(grid), len(grid[0]) max_area = 0 def bfs(r, c): queue = deque([(r, c)]) grid[r][c] = 0 # Помечаем как посещённый area = 1 while queue: row, col = queue.popleft() for dr, dc in [(1,0), (-1,0), (0,1), (0,-1)]: nr, nc = row + dr, col + dc if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1: grid[nr][nc] = 0 area += 1 queue.append((nr, nc)) return area for i in range(rows): for j in range(cols): if grid[i][j] == 1: max_area = max(max_area, bfs(i, j)) return max_area

Объяснение:

  • BFS возвращает площадь компоненты
  • Обнуляем посещённые клетки (вместо visited set)
  • Обновляем максимум после каждого острова

Сложность:

  • Время: O(m × n)
  • Память: O(min(m, n))

#5. Шпаргалка

ЗадачаКлючевая идея
Number of IslandsBFS для каждой '1', mark as '0'
Rotting OrangesМногоисточниковый BFS, счётчик fresh
Walls and GatesМногоисточниковый BFS от ворот
Max Area of IslandBFS с подсчётом площади

#6. ⚠️ Common Mistakes

#❌ Ошибка 1: Забыли счётчик свежих апельсинов

Проблема: В Rotting Oranges нужно проверять, остались ли свежие.

# ❌ Неправильно — нет проверки fresh while queue: ... return minutes # Может вернуть минуты, даже если остались свежие! # ✅ Правильно while queue and fresh > 0: ... return minutes if fresh == 0 else -1

Почему это неправильно: Если остались свежие апельсины, возвращаем -1.


#❌ Ошибка 2: Неправильная инициализация многоисточникового BFS

Проблема: Нужно добавить все источники в очередь изначально.

# ❌ Неправильно — только один источник queue = deque([(start_row, start_col)]) # ✅ Правильно — все источники for i in range(rows): for j in range(cols): if grid[i][j] == 0: # Все ворота/гнилые queue.append((i, j))

Почему это неправильно: Многоисточниковый BFS требует все начальные точки в очереди.


#7. Заключение

BFS: Задачи на сетках — многоисточниковый BFS для распространения и подсчёта компонент.

Ключевые приёмы:

  1. Многоисточниковый BFS — все источники в очереди изначально
  2. Mark as visited через модификацию сетки ('1' → '0')
  3. Счётчик свежих/недостижимых элементов

Далее: BFS: Кратчайший путь