题目链接:LeetCode 1020 飞地的数量
题目大意:
题解:
很显然,边缘的\(1\)或者与边缘的\(1\)直接或间接相连的\(1\)可以离开网格边界。
从外向内搜索与边缘的\(1\)直接或间接相连的\(1\),并打上标记,再遍历数组统计未打上标记的\(1\)的个数。
class Solution {
private:
vector<vector<int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
public:
int numEnclaves(vector<vector<int>>& grid) {
int n = grid.size(), m = grid[0].size();
vector<vector<bool>> vis(n, vector<bool>(m, false));
queue<pair<int, int>> q;
for (int i = 0; i < m; ++i) {
if (grid[0][i]) {
vis[0][i] = true;
q.emplace(0, i);
}
if (grid[n - 1][i]) {
vis[n - 1][i] = true;
q.emplace(n - 1, i);
}
}
for (int i = 1; i < n - 1; ++i) {
if (grid[i][0]) {
vis[i][0] = true;
q.emplace(i, 0);
}
if (grid[i][m - 1]) {
vis[i][m - 1] = true;
q.emplace(i, m - 1);
}
}
while (!q.empty()) {
auto& [x, y] = q.front();
for (auto& dir : dirs) {
int nx = x + dir[0], ny = y + dir[1];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] && !vis[nx][ny]) {
vis[nx][ny] = true;
q.emplace(nx, ny);
}
}
q.pop();
}
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (grid[i][j] && !vis[i][j]) {
ans++;
}
}
}
return ans;
}
};