leetcode1020. 飞地的数量
挺简单的。dfs解法:
class Solution {
public:
int m, n; // 定义网格的行数m和列数n
// 深度优先搜索函数,用于标记所有可以到达边界的陆地单元格
void dfs(vector<vector<int>>& grid, int i, int j) {
// 检查是否越界
if (i == -1 || i == grid.size() || j == -1 || j == grid[0].size())
return;
// 检查当前单元格是否是陆地(1),如果不是则返回
if (grid[i][j] != 1)
return;
// 将当前陆地单元格标记为已访问(2)
grid[i][j] = 2;
// 递归搜索四个方向
dfs(grid, i-1, j); // 上
dfs(grid, i+1, j); // 下
dfs(grid, i, j-1); // 左
dfs(grid, i, j+1); // 右
}
int numEnclaves(vector<vector<int>>& grid) {
m = grid.size(), n = grid[0].size(); // 获取网格的行数和列数
int res = 0; // 初始化结果为0,用于计数封闭的陆地单元格
// 第一步:处理所有边界上的陆地单元格
// 遍历第一列和最后一列
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 1) // 检查第一列的陆地
dfs(grid, i, 0); // 进行深度优先搜索标记
if (grid[i][n-1] == 1) // 检查最后一列的陆地
dfs(grid, i, n-1); // 进行深度优先搜索标记
}
// 遍历第一行和最后一行的中间部分(避免重复处理四个角)
for (int j = 1; j < n - 1; ++j) {
if (grid[0][j] == 1) // 检查第一行的陆地
dfs(grid, 0, j); // 进行深度优先搜索标记
if (grid[m-1][j] == 1) // 检查最后一行的陆地
dfs(grid, m-1, j); // 进行深度优先搜索标记
}
// 第二步:统计剩余的未被标记的陆地单元格(即封闭的陆地)
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) // 如果还是1,表示是封闭的陆地
++res; // 计数器加1
}
}
return res; // 返回封闭陆地的总数
}
};
deepseek v3 写的BFS解法:
class Solution {
public:
int m,n;
int numEnclaves(vector<vector<int>>& grid) {
m = grid.size(),n = grid[0].size();
int res = 0;
// 定义四个方向的偏移量:上、右、下、左
vector<pair<int, int>> directions = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
queue<pair<int, int>> q; // BFS队列
// 第一步:处理所有边界上的陆地单元格
// 遍历第一列和最后一列
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 1) { // 第一列
grid[i][0] = 2; // 标记为已访问
q.push({i, 0}); // 加入队列
}
if (grid[i][n-1] == 1) { // 最后一列
grid[i][n-1] = 2;
q.push({i, n-1});
}
}
// 遍历第一行和最后一行的中间部分(避免重复处理四个角)
for (int j = 1; j < n - 1; ++j) {
if (grid[0][j] == 1) { // 第一行
grid[0][j] = 2;
q.push({0, j});
}
if (grid[m-1][j] == 1) { // 最后一行
grid[m-1][j] = 2;
q.push({m-1, j});
}
}
// 执行BFS,标记所有能到达边界的陆地
while (!q.empty()) {
auto [x, y] = q.front();
q.pop();
// 检查四个方向
for (auto [dx, dy] : directions) {
int nx = x + dx;
int ny = y + dy;
// 检查是否在网格范围内且是未访问的陆地
if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1) {
grid[nx][ny] = 2; // 标记为已访问
q.push({nx, ny}); // 加入队列继续搜索
}
}
}
// 第二步:统计剩余的未被标记的陆地单元格(即封闭的陆地)
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
++res;
}
}
}
return res;
}
};