Сложность: hard
Дана сетка m x n, содержащая значения 0, 1 или 2, где:
каждое 0 обозначает пустую землю, по которой можно свободно проходить,
каждое 1 обозначает здание, через которое нельзя пройти,
каждое 2 обозначает препятствие, через которое нельзя пройти.
Вы хотите построить дом на пустой земле, чтобы он достиг всех зданий с минимальным суммарным расстоянием. Можно перемещаться только вверх, вниз, влево и вправо.
Верните минимальное суммарное расстояние для такого дома. Если построить такой дом невозможно согласно указанным правилам, верните -1.
Суммарное расстояние — это сумма расстояний между домами друзей и точкой встречи.
Пример:
Input: grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
Output: 7
👨💻 Алгоритм:
1⃣Инициализация и запуск BFS
Для каждой пустой ячейки (0) в сетке grid запустите BFS, обходя все соседние ячейки в 4 направлениях, которые не заблокированы и не посещены, отслеживая расстояние от начальной ячейки.
2⃣Обработка BFS и обновление расстояний
При достижении здания (1) увеличьте счетчик достигнутых домов housesReached и суммарное расстояние distanceSum на текущее расстояние. Если housesReached равно общему количеству зданий, верните суммарное расстояние. Если BFS не может достигнуть всех домов, установите значение каждой посещенной пустой ячейки в 2, чтобы не запускать новый BFS из этих ячеек, и верните INT_MAX.
3⃣Обновление и возврат минимального расстояния
Обновите минимальное расстояние (minDistance) после каждого вызова BFS. Если возможно достигнуть все дома из любой пустой ячейки, верните найденное минимальное расстояние. В противном случае, верните -1.
😎 Решение:
#include <vector>
#include <queue>
#include <climits>
using namespace std;
class Solution {
private:
int bfs(vector<vector<int>>& grid, int row, int col, int totalHouses) {
int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int rows = grid.size(), cols = grid[0].size();
int distanceSum = 0, housesReached = 0, steps = 0;
queue<pair<int, int>> q;
q.push({row, col});
vector<vector<bool>> vis(rows, vector<bool>(cols, false));
vis[row][col] = true;
while (!q.empty() && housesReached != totalHouses) {
int size = q.size();
while (size-- > 0) {
auto curr = q.front();
q.pop();
int r = curr.first, c = curr.second;
if (grid[r][c] == 1) {
distanceSum += steps;
housesReached++;
continue;
}
for (auto& dir : dirs) {
int nr = r + dir[0], nc = c + dir[1];
if (nr >= 0 && nc >= 0 && nr < rows && nc < cols && !vis[nr][nc] && grid[nr][nc] != 2) {
vis[nr][nc] = true;
q.push({nr, nc});
}
}
}
steps++;
}
if (housesReached != totalHouses) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == 0 && vis[r][c]) grid[r][c] = 2;
}
}
return INT_MAX;
}
return distanceSum;
}
public:
int shortestDistance(vector<vector<int>>& grid) {
int minDistance = INT_MAX, rows = grid.size(), cols = grid[0].size(), totalHouses = 0;
for (const auto& row : grid) for (const auto& cell : row) if (cell == 1) totalHouses++;
for (int r = 0; r < rows; r++) for (int c = 0; c < cols; c++) if (grid[r][c] == 0) minDistance = min(minDistance, bfs(grid, r, c, totalHouses));
return minDistance == INT_MAX ? -1 : minDistance;
}
};
Ставь 👍 и забирай 📚 Базу знаний
